CSS clip-path 마스크 효과와 스크롤 기반 이미지 전환(슬라이드) 구현 방법
CSS 25.08.04CSS clip-path 마스크 효과와 스크롤 기반 이미지 전환(슬라이드) 구현 방법
CSS clip-path를 활용해 세련된 이미지 마스크 효과를 구현하고,
GSAP ScrollTrigger로 스크롤에 따라 이미지가 자연스럽게 전환되는 슬라이드 모션을 만드는 방법을 소개합니다.
마스킹 디자인과 스크롤 애니메이션을 결합해 인터랙티브한 웹 페이지를 제작해보세요.
✅ 한 눈에 알아보기
1. HTML에 여러 장의 이미지를 배치하고 각 이미지를 clip-path로 마스킹 처리
2. ScrollTrigger를 사용해 스크롤 위치에 맞춰 이미지 슬라이드 전환
➰➰➰
✅ clip-path란?
✔ clip-path는 HTML 요소를 지정한 모양(도형, SVG path 등)에 맞춰 잘라내는 CSS 속성입니다.
✔ 이미지를 특정 형태로 마스킹할 수 있어, 기존의 사각형 이미지보다 더 독창적인 레이아웃을 만들 수 있습니다.
✨ clip-path 속성은 복잡한 도형이나 곡선을 직접 작성하기 어려울 수 있습니다.
이럴 때는 Clippy 같은 온라인 도구나 AI 기반 코드 생성기를 활용하면, 더 자연스럽고 직관적인 마스크 모양을 빠르게 만들 수 있어 효율적입니다.
✏️ HTML 구조는 이렇게 생겼어요
✔ 이미지 마스크를 적용시킬 대표 frame을 생성합니다.
✔ clip-path 소스코드와 frame안에서 슬라이드시킬 이미지 (frame-box)를 배치합니다.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <section id="inc03"> <div class="cont"> <div class="sticky-wrap"> <div class="cont__img"> <div class="frame-wrap"> <svg width="0" height="0" aria-hidden="true" style="position:absolute;overflow:hidden;"> <defs> <clipPath id="frameMask" clipPathUnits="objectBoundingBox"> <path d="M 0 0 Q 0.0636 0.5 0 1 L 1 1 Q 0.936 0.5 1 0 Z" /> </clipPath> </defs> </svg> <div class="frame-box"> <div class="overlay"></div> <img src="img/inc03_img01.jpg" alt="Sample display"> <div class="tit_area"> <h2 class="tit">Sample display</h2> </div> </div> <div class="frame-box"> <div class="overlay"></div> <img src="img/inc03_img02.jpg" alt="CleanFit"> <div class="tit_area"> <h2 class="tit">CleanFit</h2> </div> </div> <div class="frame-box"> <div class="overlay"></div> <img src="img/inc03_img03.jpg" alt="Bookfolio"> <div class="tit_area"> <h2 class="tit">Bookfolio</h2> </div> </div> <div class="frame-box"> <div class="overlay"></div> <img src="img/inc03_img04.jpg" alt="Medilink"> <div class="tit_area"> <h2 class="tit">Medilink</h2> </div> </div> <div class="frame-box"> <div class="overlay"></div> <img src="img/inc03_img05.jpg" alt="Creaty"> <div class="tit_area"> <h2 class="tit">Creaty</h2> </div> </div> </div> </div> </div> </div> </section> | cs |
✏️ CSS로 효과 구현하기
✔ 대표 frame에 url(#frameMask) 속성을 활용하여 SVG에 정의된 마스크 경로를 불러와 적용합니다.
복잡하고 정교한 프레임 형태를 쉽게 구현할 수 있고, 벡터 기반이라 반응형에서도 선명하게 표현됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #inc03{position:relative;padding-bottom:103px;max-width:var(--main-size);margin:0 auto} #inc03 .cont{height:400vh} #inc03 .sticky-wrap{position:sticky;top:0;overflow:hidden;display:flex;align-items:center;justify-content:center;height:100vh;padding:0 50px;margin-bottom:150px} /* 이미지 프레임 */ #inc03 .cont__img{position:relative;display:flex;justify-content:center;width:100%} #inc03 .cont__img .img-item picture{position:relative;display:block;overflow:hidden} #inc03 .cont__img .frame-wrap{position:relative;overflow:hidden;display:flex;flex-direction:column;max-width:1100px;min-width:110px;width:100%;aspect-ratio:3/2;clip-path:url(#frameMask);-webkit-clip-path:url(#frameMask);transform:rotate(-5deg)} #inc03 .cont__img .frame-wrap .overlay{position:absolute;inset:0%;width:100%;height:100%;background-color:rgba(0,0,0,0.3);pointer-events:none} #inc03 .cont__img .frame-box{position:relative} #inc03 .cont__img .frame-box img{width:100%;object-fit:cover} #inc03 .cont__img .frame-box .tit_area{position:absolute;top:50%;left:50%;display:flex;flex-direction:column;align-items:center;width:100%;transform:translate(-50%, -50%) rotate(5deg)} #inc03 .cont__img .frame-box .tit_area .tit{font-family:var(--e-font);font-size:clamp(100px, 8.67vw, 150px);font-weight:400;line-height:100%;color:var(--point);text-align:center;text-transform:uppercase} #inc03 .cont__img .frame-box .tit_area .desc{font-family:var(--k-font);font-size:15px;font-weight:700;line-height:100%;text-transform:uppercase;color:var(--point)} | cs |
✏️ GSAP로 애니메이션 구현하기
self.progress
✔ 0~1 사이의 값으로 스크롤 진행도를 나타냅니다. (start 지점에서는 0, end 지점에서는 1)
✔ progress 값에 (슬라이드 개수 - 1)을 곱해 슬라이드 인덱스로 변환합니다.
-1을 하는 이유는 마지막 이미지는 슬라이드 되지 않기 때문입니다.
✔ 현재 인덱스에 맞게 전체 이미지를 이동시킵니다. -100%, -200%, -300% 씩 차례로 이동시키면 각 인덱스에 맞는 이미지가 노출됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | const frameBox = document.querySelectorAll('#inc03 .cont__img .frame-box'); const totalFrame = frameBox.length; ScrollTrigger.create({ trigger:"#inc03", start:"top top", end:"70% bottom", scrub:1, onUpdate:(self) => { const idx = Math.floor(self.progress*(totalFrame - 1)); gsap.to(frameBox,{yPercent: -100 * idx}); } }); | cs |
See the Pen CSS clip-path 마스크 효과와 스크롤 기반 이미지 전환(슬라이드) 구현 방법 by designkits (@designkits) on CodePen.