| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- php
- CGIMALL
- 홈페이지
- #이미지
- #happycgi
- jquery
- #jQuery
- 해피CGI
- #홈페이지
- 솔루션
- #뉴스
- CSS
- 사이트제작
- 해피씨지아이
- #해피CGI
- #cgimall
- #쇼핑몰
- happycgi
- 이미지
- #웹솔루션
- 웹솔루션
- #업종별
- #image
- 게시판
- #CSS
- #솔루션
- #동영상
- 홈페이지제작
- javascript
- #홈페이지제작
- 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] CrowdSec 실시간 공격 탐지 및 자동 차단 보안 시스템 (0) | 2026.06.12 |
|---|---|
| [해피CGI][cgimall] Bad ASN List 악성 ASN 차단 리스트 (0) | 2026.06.11 |
| [해피CGI][cgimall] 반응형이 지원되는 이미지 슬라이드 Responsive Image Slider (0) | 2026.06.10 |
| [해피CGI][cgimall] HTML와 CSS를 이용한 아코디언 메뉴 Awesome accordion menu using only HTML & CSS (0) | 2026.06.09 |
| [해피CGI][cgimall] Direction-Aware Hover with Modern CSS (0) | 2026.06.05 |

