본문 바로가기

비개발자의 개발 일지

현장 팀장에서 수출 ERP까지 — AI와 함께 시스템을 만든 기록

시리즈 보기
php

상품 카드 hover 시 caption 슬라이드 업 — translateY · opacity · overflow:hidden 완전 정리

by 왕진 2026. 6. 20.
반응형

 

 

Web Development · CSS Hover Slide

상품 카드 hover 시 caption이
아래에서 슬라이드 업 되는 원리

overflow:hidden · position 조합 · translateY · opacity 전환
시작 오늘 분석할 코드

쇼핑몰에서 자주 보는 패턴이다. 평소에는 상품 이미지만 보이다가, 마우스를 올리면 설명·가격이 적힌 검은 반투명 박스가 아래에서 슬라이드 업 하면서 이미지를 덮는다. 핵심 트릭은 caption을 처음부터 화면에 그려두지 않고, 이미지 바로 아래(보이지 않는 곳)에 숨겨두었다가 hover 시 위로 끌어올리는 것이다.

<style> .prod-list { list-style: none; margin: 0; padding: 0; } .prod-list li { position: relative; float: left; margin: 10px; overflow: hidden; /* 핵심: 비어져 나간 caption을 잘라냄 */ } .prod-list img { float: left; z-index: 5; } .prod-list .caption { position: absolute; top: 200px; /* 평소: 이미지 아래 (li 영역 밖) */ width: 300px; height: 200px; padding-top: 20px; background: rgba(0,0,0,0.6); opacity: 0; /* 평소: 안 보임 */ transition: all 0.2s ease-in-out; z-index: 10; /* 이미지보다 위 */ } .prod-list li:hover .caption { opacity: 1; /* 보이게 */ transform: translateY(-200px); /* 200px 위로 이동 */ } </style> <ul class="prod-list"> <li> <img src="images/prod1.jpg"> <div class="caption"> <h1>상품 1</h1> <p>상품 1 설명 텍스트</p> <p>가격 : 12,345원</p> </div> </li> <!-- 같은 구조로 li 2개 더 --> </ul>
실제 출력 미리보기 — 상품 카드에 마우스를 올려보세요
  • 상품 1

    상품 1

    상품 1 설명 텍스트

    가격 : 12,345원

  • 상품 2

    상품 2

    상품 2 설명 텍스트

    가격 : 12,345원

  • 상품 3

    상품 3

    상품 3 설명 텍스트

    가격 : 12,345원

평소엔 이미지만 / hover 시 검은 박스가 아래에서 위로 슬라이드
용어 용어 정리
position:relative자식의 absolute 기준점이 됨
position:absolute기준점 위에 자유롭게 위치 지정
overflow:hidden박스 밖으로 삐져나간 부분을 잘라냄
opacity0(투명)~1(불투명) 사이 투명도
translateY(-200px)y축 방향 -200px(위로) 이동
z-index겹쳐진 요소의 위·아래 순서
rgba(0,0,0,0.6)검정 + 60% 불투명 → 반투명 효과
transition상태 변화 시 부드러운 보간

1 핵심 아이디어 — caption은 "처음부터 아래에 있다"

이 코드의 가장 중요한 발상은 caption이 hover 순간 없다가 새로 만들어지는 게 아니라, 처음부터 li 영역 바로 아래(top:200px) 자리에 그려져 있다는 점이다. 평소엔 두 가지 장치로 안 보이게 처리한다.

장치 1 — overflow:hidden
  • li 박스 밖으로 삐져나간 부분 잘라냄
  • caption은 top:200px → li 아래쪽 → 잘려서 안 보임
  • 이게 없으면 평소에도 카드 밑에 caption이 보임
장치 2 — opacity:0
  • 완전 투명 — 위치는 그대로지만 시각적으로 0
  • hover 시 1로 페이드인
  • 이중 안전장치 + 페이드 효과까지 부여
display:none이 아니라 opacity:0을 쓴 이유: display:none은 transition이 안 먹는다. 부드러운 페이드를 주려면 opacity여야 한다.

2 position:relative + position:absolute 조합
왜 이 조합이 거의 항상 같이 등장하는가?

absolute는 "가장 가까운 position이 지정된 조상"을 기준으로 위치한다. 이번 코드에서 만약 li에 position:relative가 없다면, caption은 화면(body) 기준 top:200px로 가버려서 카드 아래가 아니라 페이지 어딘가에 떠다니게 된다.

.prod-list li { position: relative; } ← 기준점 선언 .prod-list .caption { position: absolute; top: 200px; } ← 기준점에서 아래로 200px
※ "relative + absolute" 패턴 외우기
  • 오버레이를 깔고 싶으면 → 부모 relative + 자식 absolute
  • 모달 띄우고 싶으면 → body·section relative + 자식 absolute (또는 fixed)
  • tooltip 띄우고 싶으면 → 호버 대상 relative + tooltip absolute

3 top:200px의 의미 — 아래에 숨겨두기

이번 코드의 이미지 높이가 200px이다. caption도 height:200px이다. top:200px은 caption을 이미지의 정확히 아래 칸에 배치한다.

┌──────────────┐ top: 0 ← li 영역 시작 │ │ │ 이미지 │ 높이 200px │ │ ├──────────────┤ top: 200px ← caption 시작 위치 (평소) │ │ │ caption │ → li 밖 → overflow:hidden으로 잘림 │ │ └──────────────┘

hover 시 translateY(-200px)로 caption을 200px 위로 끌어올리면, 이미지 위치를 정확히 덮는다.


 

반응형

 

4 translateY vs top — 왜 굳이 transform을 쓰는가?

"caption을 위로 올리고 싶다"면 top: 0으로 바꿔도 결과는 같아 보인다. 하지만 두 방식은 성능과 부드러움이 다르다.

방식 처리 단계 부드러움
top 변경 레이아웃 → 페인트 → 합성 박스 위치 재계산 발생, 끊겨 보일 수 있음
transform 변경 합성만 (GPU 가속) 레이아웃 영향 없음 → 부드러움
※ "위치를 바꾼다"가 같은 의미여도 transform을 쓰는 게 모범 답안이다. 특히 모바일에서 차이가 크다.

5 rgba(0,0,0,0.6) — 반투명 검정의 효과

그냥 black이면 caption이 이미지를 완전히 가린다. rgba(0,0,0,0.6)검정 + 60% 불투명으로, 뒤의 이미지가 살짝 비치면서 텍스트가 잘 읽힌다.

rgba(R, G, B, A) R, G, B → 0~255 색상값 A → 0(투명)~1(불투명) 알파값 rgba(0, 0, 0, 0) → 완전 투명 rgba(0, 0, 0, 0.6) → 60% 검정 (이번 코드) rgba(0, 0, 0, 1) → 완전 검정 = #000

6 z-index — 누가 위에 보일지

이번 코드에서 imgz-index:5, captionz-index:10이다. 숫자가 클수록 위에 그려진다. caption이 슬라이드업 했을 때 이미지를 덮어야 하니까 caption 쪽이 더 커야 한다.

※ z-index 함정
  • position: static(기본값)인 요소엔 z-index가 안 먹힌다
  • relative, absolute, fixed, sticky 중 하나여야 효과 있음
  • 이번 코드는 caption이 absolute, img는 float 상태 — 같은 stacking 컨텍스트 안에서 비교

7 hover 흐름 단계별 정리
1
평소 상태caption은 top:200px 위치에 있지만, li의 overflow:hidden + opacity:0 때문에 안 보임
2
li에 마우스 진입:hover 발동 → .prod-list li:hover .caption 규칙 적용
3
opacity 0 → 1 (페이드인)0.2초에 걸쳐 점점 불투명해짐
4
translateY 0 → -200px (슬라이드업)같은 0.2초 동안 위로 끌어올라감 — 두 효과가 동시에 발생
5
이미지 위에 캡션 안착caption이 이미지를 60% 검정 반투명으로 덮음
6
마우스가 li를 벗어남역방향 transition 재생 → 다시 아래로 슬라이드 + 페이드아웃

8 자주 하는 실수
실수 증상 해결
li에 position:relative 빠뜨림 caption이 페이지 어딘가로 날아감 부모 li에 relative 명시
overflow:hidden 빠뜨림 평소에도 caption이 카드 밑에 보임 li에 overflow:hidden
caption에 transition 없음 딸깍 — 점프하듯 나타남 caption 평소 상태에 transition 정의 (양방향 적용)
display:none으로 숨김 페이드 효과가 안 먹음 opacity:0 + transition
hover 상태에 transition 정의 들어갈 땐 부드럽고 나올 땐 점프 transition은 항상 평소 상태에 정의
z-index가 caption < img caption이 이미지 뒤로 가려져 안 보임 caption의 z-index를 img보다 크게
top 변경으로 슬라이드 버벅거림, 모바일에서 끊김 transform: translateY로 GPU 가속

9 현대식 대안 — float 대신 flex/grid

이번 원본은 float:left로 카드를 가로 정렬했다. 2026년 기준 권장은 부모에 flex나 grid를 주는 방식이다.

옛 방식 (float)
.prod-list li {
  float: left;
}


clearfix 필요, 반응형 어려움
현대식 (flex)
.prod-list {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}


정렬·간격이 한 번에 깔끔

핵심 한 줄 요약

overflow:hiddenli 밖 caption을 잘라 평소엔 안 보이게
relative + absolute부모 기준점 + 자식 자유 배치 (오버레이의 정석)
top: 200pxcaption의 평소 위치 — 이미지 정확히 아래 칸
opacity: 0 → 1페이드 효과 — display:none 대신
translateY(-200px)위로 200px 슬라이드 — 이미지를 덮음
rgba(0,0,0,0.6)반투명 검정 — 텍스트 가독성 + 이미지 비침
z-indexcaption(10) > img(5) — 위에 그려짐
transition평소 상태에 정의해야 양방향 부드러움

Tags

#hover #caption #translateY #opacity #overflow-hidden #position-absolute #z-index #rgba #transition #transform #CSS #HTML #슬라이드업 #상품카드 #오버레이 #웹개발 #티스토리
▼ 티스토리 태그 입력란 복사용
hover, caption, translateY, opacity, overflow-hidden, position-absolute, position-relative, z-index, rgba, transition, transform, CSS, HTML, 슬라이드업, 상품카드, 오버레이, 웹개발, 티스토리
반응형

댓글