| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- #쇼핑몰
- #이미지
- 사이트제작
- #해피CGI
- jquery
- #jQuery
- #happycgi
- #동영상
- 이미지
- CGIMALL
- #업종별
- php
- #홈페이지
- 해피씨지아이
- happycgi
- #웹솔루션
- 홈페이지제작
- #솔루션
- #뉴스
- #홈페이지제작
- 솔루션
- #cgimall
- javascript
- 홈페이지
- 게시판
- #image
- 해피CGI
- CSS
- #CSS
- 웹솔루션
- Today
- Total
웹솔루션개발 26년 노하우! 해피CGI의 모든것
[해피CGI][cgimall] 스크롤 인터랙션 확장형 이미지 갤러리 UI 본문
CSS Grid 기반으로 구성된 이미지 갤러리에서 특정 요소 hover 시 해당 영역이 확장되도록 구현된 인터랙션이다.
:has() 선택자를 활용하여 부모 요소에서 자식 hover 상태를 감지하고 레이아웃을 동적으로 변경한다.
이미지는 겹치는 grid 구조와 비율 변화를 통해 자연스럽게 확장되며 시각적인 몰입감을 제공한다.
별도의 JavaScript 없이 순수 CSS만으로 구현된 구조로, 최신 브라우저 환경에서 활용 가능한 UI 패턴이다.

HTML 구조
<div class="wrapper">
<div style="--bg-img:url(https://images.unsplash.com/photo-1518005020951-eccb494ad742?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3Njg0MjEyODh8&ixlib=rb-4.1.0&q=80&w=400)"></div>
<div style="--bg-img:url(https://images.unsplash.com/photo-1479839672679-a46483c0e7c8?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3Njg0MjA1MDB8&ixlib=rb-4.1.0&q=80&w=400)"> </div>
<div style="--bg-img:url(https://images.unsplash.com/photo-1493397212122-2b85dda8106b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3Njg0MjA4MTB8&ixlib=rb-4.1.0&q=80&w=400)"></div>
<div style="--bg-img:url(https://images.unsplash.com/photo-1524126675694-1efa3488b7c0?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3Njg0MjA1MjR8&ixlib=rb-4.1.0&q=80&w=400)"></div>
</div>
CSS 소스
@import url(https://fonts.bunny.net/css?family=jura:300,500);
@layer base, demo;
@layer demo {
/* demo code goes here */
.wrapper{
--border-size: 5px;
--border-color: var(--bg-light);
/* default gid columns - note, to animatbale we need to defined them individually */
--grid-cols: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr ;
display: grid;
grid-template-columns: var(--grid-cols);
width:min(100%,800px);
margin-inline: auto;
aspect-ratio: 2/1;
transition: grid 300ms ease-in-out;
counter-reset: --card-counter;
/* define grid columns according to which one has hover */
&:has(:nth-child(1):hover){ --grid-cols: 6fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr; }
&:has(:nth-child(2):hover){ --grid-cols: 1fr 1fr 1fr 6fr 1fr 1fr 1fr 1fr 1fr; }
&:has(:nth-child(3):hover){ --grid-cols: 1fr 1fr 1fr 1fr 1fr 6fr 1fr 1fr 1fr; }
&:has(:nth-child(4):hover){ --grid-cols: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 6fr 1fr; }
& > *{
position: relative;
overflow: hidden;
border-radius: 0 0 0 30%/ 0 0 0 50% ;
&:first-child{
border-radius: 0 0 0 0/ 0 0 0 200px ;
}
corner-shape:notch;
transition: all 300ms ease-in-out;
border: var(--border-size) solid var(--border-color);
background-image: var(--bg-img);
background-size: 450px 100%; /* requires fixed width to maintain size and aspect */
/* remove notch from current and next sibling on hover*/
&:hover,
&:hover + div{
border-radius: 0 0 0 0;
}
/* define grid position - each element overlaps by 1 column */
grid-row: 1;
&:nth-child(1){ grid-column: 1 / span 3; }
&:nth-child(2){ grid-column: 3 / span 3; }
&:nth-child(3){ grid-column: 5 / span 3; }
&:nth-child(4){ grid-column: 7 / span 3; }
/* image counter - could easily be a title */
&::after{
content: counter(--card-counter) ".";
counter-increment: --card-counter;
position: absolute;
top: .5rem;
left: 1rem;
font-size: 2rem;
transition: scale 150ms ease-in-out;
scale: 0;
}
&:hover::after{
scale: 1;
}
}
}
}
/* general styling not relevant for this demo */
@layer base {
* {
box-sizing: border-box;
}
:root {
color-scheme: light dark;
--bg-dark: rgb(16, 24, 40);
--bg-light: rgb(248, 244, 238);
--txt-light: rgb(10, 10, 10);
--txt-dark: rgb(245, 245, 245););
--line-light: rgba(0 0 0 / .25);
--line-dark: rgba(255 255 255 / .25);
--clr-bg: light-dark(var(--bg-light), var(--bg-dark));
--clr-txt: light-dark(var(--txt-light), var(--txt-dark));
--clr-lines: light-dark(var(--line-light), var(--line-dark));
}
body {
background-color: var(--clr-bg);
color: var(--clr-txt);
min-height: 100svh;
margin: 0;
padding: 2rem;
font-family: "Jura", sans-serif;
font-size: 1rem;
line-height: 1.5;
display: grid;
place-items: center;
gap: 2rem;
}
}
'웹프로그램밍 자료실 > 기타 자료' 카테고리의 다른 글
| [해피CGI][cgimall] Cred App Like Tab Bar Interaction 탭메뉴 css 상호작용 (0) | 2026.06.18 |
|---|---|
| [해피CGI][cgimall] 스크롤 상태 기반 Sticky 네비게이션 UI (0) | 2026.06.16 |
| [해피CGI][cgimall] CrowdSec 실시간 공격 탐지 및 자동 차단 보안 시스템 (0) | 2026.06.12 |
| [해피CGI][cgimall] Bad ASN List 악성 ASN 차단 리스트 (0) | 2026.06.11 |
| [해피CGI][cgimall] 반응형이 지원되는 이미지 슬라이드 Responsive Image Slider (0) | 2026.06.10 |

