CSS Scroll-Driven Animations: 스크롤에 반응하는 동적인 웹 경험 만들기
CSS Scroll-Driven Animations를 사용하여 JavaScript 없이도 스크롤에 반응하는 동적이고 인터랙티브한 웹 경험을 구현하는 방법을 알아봅니다. `@scroll-timeline`과 `animation-timeline`을 활용한 페이드 인, 이미지 갤러리 효과 예제와 브라우저 지원 현황까지 다룹니다.
스크롤에 반응하는 동적인 웹 경험 만들기: CSS Scroll-Driven Animations
웹사이트를 탐색하다 보면 스크롤을 내릴 때마다 콘텐츠가 부드럽게 나타나거나, 요소의 스타일이 변하는 것을 본 경험이 있을 것입니다. 이러한 동적인 스크롤 애니메이션은 사용자 경험을 풍부하게 만들고 콘텐츠에 대한 몰입도를 높이는 데 중요한 역할을 합니다. 기존에는 JavaScript를 사용하여 스크롤 이벤트를 감지하고 복잡한 로직을 구현해야 했지만, 이제 CSS만으로도 이러한 동적인 스크롤 애니메이션을 훨씬 쉽고 효율적으로 구현할 수 있게 되었습니다. 바로 CSS Scroll-Driven Animations (SDA) 덕분입니다.
Scroll-Driven Animations란 무엇인가?
Scroll-Driven Animations는 웹 애니메이션 API(Web Animations API, WAAPI)의 확장 기능으로, 스크롤 컨테이너의 스크롤 위치 변화에 따라 애니메이션의 재생/일시정지, 재생 속도, 진행률 등을 제어할 수 있게 해주는 새로운 CSS 기능입니다. 즉, 사용자가 페이지를 스크롤하는 행위 자체가 애니메이션의 트리거가 되는 것입니다.
기존의 JavaScript 기반 스크롤 애니메이션은 scroll 이벤트를 지속적으로 감지하고, 각 스크롤 이벤트마다 애니메이션 상태를 계산해야 했습니다. 이는 성능 이슈를 야기할 수 있으며, 구현 또한 복잡했습니다. 하지만 Scroll-Driven Animations는 이러한 부담을 브라우저에 위임하여 훨씬 부드럽고 효율적인 애니메이션을 구현할 수 있게 합니다.
어떻게 작동하는가?
Scroll-Driven Animations는 @scroll-timeline 과 animation-timeline 이라는 두 가지 새로운 CSS 규칙을 통해 작동합니다.
-
@scroll-timeline: 스크롤 애니메이션의 기준이 되는 스크롤 컨테이너와 스크롤축(수직/수평)을 정의합니다.source속성으로 스크롤 컨테이너를 지정하고,orientation으로 스크롤 방향을 설정합니다.scroll-offsets를 사용하여 스크롤 위치에 따른 애니메이션의 시작 및 끝 지점을 세밀하게 제어할 수도 있습니다.1@scroll-timeline scroll-in-a-box { 2 source: "#scrollable-element"; 3 orientation: "block"; /* "inline" 또는 "both"도 가능 */ 4 scroll-offsets: 0, 100%; /* 스크롤 시작 시 0%, 끝날 때 100% */ 5} -
animation-timeline: 특정 CSS 애니메이션(animation-name)이 위에서 정의한@scroll-timeline을 따르도록 연결합니다.animation-timeline속성 값으로@scroll-timeline에서 정의한 이름을 지정하면 됩니다.1.animate-me { 2 animation-name: fade-in; 3 animation-timeline: scroll-in-a-box; 4 animation-fill-mode: both; 5} 6 7@keyframes fade-in { 8 from { opacity: 0; transform: translateY(20px); } 9 to { opacity: 1; transform: translateY(0); } 10}
위 예제에서 .animate-me 클래스를 가진 요소는 #scrollable-element라는 ID를 가진 요소가 스크롤될 때 fade-in 애니메이션이 적용됩니다. scroll-offsets 설정에 따라 스크롤이 #scrollable-element의 시작 부분에 도달하면 애니메이션이 시작되고, 끝 부분에 도달하면 완료됩니다.
실제 적용 예시: 페이드 인 효과
가장 흔하게 사용되는 스크롤 애니메이션 중 하나는 스크롤 시 요소가 부드럽게 나타나는 페이드 인(Fade-in) 효과입니다. Scroll-Driven Animations를 사용하면 이를 매우 간결하게 구현할 수 있습니다.
HTML:
1<div class="scroll-container"> 2 <div class="spacer"></div> 3 <div class="content-item fade-in-on-scroll">첫 번째 아이템</div> 4 <div class="content-item fade-in-on-scroll">두 번째 아이템</div> 5 <div class="content-item fade-in-on-scroll">세 번째 아이템</div> 6 <div class="spacer"></div> 7</div>
CSS:
1.scroll-container { 2 height: 300vh; /* 스크롤을 위한 충분한 높이 */ 3 padding: 20px; 4 background-color: #f0f0f0; 5} 6 7.content-item { 8 height: 200px; 9 margin: 100px auto; 10 background-color: dodgerblue; 11 color: white; 12 display: flex; 13 justify-content: center; 14 align-items: center; 15 font-size: 2em; 16 opacity: 0; 17 transform: translateY(30px); 18 transition: opacity 0.6s ease-out, transform 0.6s ease-out; 19} 20 21/* Scroll-Driven Animations 정의 */ 22@scroll-timeline scroll-fade { 23 source: ".scroll-container"; 24 orientation: "block"; 25 scroll-offsets: 0, 0.5; 26} 27 28.fade-in-on-scroll { 29 animation-name: fade-in; 30 animation-timeline: scroll-fade; 31 animation-fill-mode: both; 32} 33 34@keyframes fade-in { 35 from { opacity: 0; transform: translateY(30px); } 36 to { opacity: 1; transform: translateY(0); } 37} 38 39.spacer { 40 height: 100vh; 41}
이 예제에서는 .scroll-container가 스크롤될 때, .fade-in-on-scroll 클래스를 가진 요소들이 스크롤 위치의 50% 지점에 도달했을 때 완전히 나타나도록 애니메이션을 설정했습니다. @scroll-timeline에서 scroll-offsets: 0, 0.5는 컨테이너의 시작(0%)부터 컨테이너 높이의 50% 지점까지 애니메이션이 진행됨을 의미합니다.
더 나아가기: 이미지 갤러리 효과
Scroll-Driven Animations는 단순한 페이드 인/아웃을 넘어, 스크롤에 따라 이미지의 스케일을 조절하거나 다른 요소와 동기화하는 등 더욱 복잡하고 흥미로운 효과를 구현할 수 있게 합니다.
HTML:
1<div class="gallery-container"> 2 <div class="gallery-item"> 3 <img src="image1.jpg" alt="Image 1"> 4 </div> 5 <div class="gallery-item"> 6 <img src="image2.jpg" alt="Image 2"> 7 </div> 8 <div class="gallery-item"> 9 <img src="image3.jpg" alt="Image 3"> 10 </div> 11</div>
CSS:
1.gallery-container { 2 height: 400vh; 3 display: grid; 4 grid-template-columns: repeat(3, 1fr); 5 gap: 20px; 6 padding: 50px; 7 position: relative; 8} 9 10.gallery-item { 11 background-color: #ddd; 12 display: flex; 13 justify-content: center; 14 align-items: center; 15 overflow: hidden; 16 position: sticky; 17 top: 50px; 18 height: 70vh; 19} 20 21.gallery-item img { 22 width: 100%; 23 height: 100%; 24 object-fit: cover; 25 transform-origin: center; 26 scale: 0.8; 27} 28 29/* 각 이미지에 대한 스크롤 타임라인 정의 */ 30@scroll-timeline img-scroll-1 { 31 source: ".gallery-container"; 32 orientation: "block"; 33 scroll-offsets: 0vh 0vh, 100vh 50vh; 34} 35 36@scroll-timeline img-scroll-2 { 37 source: ".gallery-container"; 38 orientation: "block"; 39 scroll-offsets: 100vh 0vh, 200vh 50vh; 40} 41 42@scroll-timeline img-scroll-3 { 43 source: ".gallery-container"; 44 orientation: "block"; 45 scroll-offsets: 200vh 0vh, 300vh 50vh; 46} 47 48/* 이미지 스케일 애니메이션 */ 49.gallery-item:nth-child(1) img { 50 animation: zoom-in; 51 animation-timeline: img-scroll-1; 52 animation-fill-mode: both; 53} 54 55.gallery-item:nth-child(2) img { 56 animation: zoom-in; 57 animation-timeline: img-scroll-2; 58 animation-fill-mode: both; 59} 60 61.gallery-item:nth-child(3) img { 62 animation: zoom-in; 63 animation-timeline: img-scroll-3; 64 animation-fill-mode: both; 65} 66 67@keyframes zoom-in { 68 from { scale: 0.8; } 69 to { scale: 1.2; } 70}
이 예제는 .gallery-container가 스크롤될 때, 각 .gallery-item의 이미지가 스크롤 위치에 따라 scale 값이 변하도록 합니다. scroll-offsets를 사용하여 각 이미지가 다른 스크롤 구간에서 애니메이션을 시작하고 종료하도록 설정하여, 스크롤에 따라 이미지가 확대/축소되는 시차 효과를 만들 수 있습니다.
주의사항 및 브라우저 지원
Scroll-Driven Animations는 비교적 최신 기능이므로 브라우저 지원 현황을 확인하는 것이 중요합니다. 현재 Chrome, Edge 등 Blink 계열 브라우저에서는 지원하지만, Firefox나 Safari 등에서는 추가적인 작업(실험적 기능 활성화 등)이 필요하거나 지원되지 않을 수 있습니다. 따라서 프로덕션 환경에 적용하기 전에 반드시 MDN Web Docs 등을 통해 최신 지원 정보를 확인하고, 폴백(fallback) 전략을 고려해야 합니다.
또한, @scroll-timeline에서 scroll-offsets를 사용할 때, 값의 단위(%, px, vh 등)와 계산 방식에 유의해야 합니다. 복잡한 레이아웃에서는 예상치 못한 결과가 나올 수 있으므로 충분한 테스트가 필요합니다.
마무리
CSS Scroll-Driven Animations는 JavaScript 없이도 동적이고 인터랙티브한 스크롤 경험을 구현할 수 있는 강력한 도구입니다. 이를 통해 개발자는 코드의 복잡성을 줄이고 성능을 개선하면서도 사용자에게 더욱 풍부한 웹 경험을 제공할 수 있습니다. 앞으로 웹 애니메이션의 새로운 지평을 열어갈 이 기술에 주목해 보시기 바랍니다.
참고 자료: