스크롤에 맞춰 요소를 움직이자고 스크롤 이벤트를 매 프레임 듣고 위치를 계산해 코드로 떠안는다 — CSS 스크롤 기반 애니메이션이 자바스크립트 없이 스크롤에 반응하는 시대

스크롤을 내릴 때 진행 막대가 차오르고, 화면에 들어온 카드가 스르르 떠오르는 화면. 예전엔 이걸 만들자고 스크롤 이벤트를 매 프레임 듣고, 요소마다 위치를 계산하고, 성능이 튀지 않게 requestAnimationFrame으로 다시 묶는 자바스크립트를 통째로 떠안아야 했다. 이제는 그 대부분을 CSS 몇 줄이 대신한다. 스크롤 기반 애니메이션(Scroll-driven Animations) 이야기다.

무엇이 달라졌나

핵심은 애니메이션의 '재생 시간'을 초 단위가 아니라 스크롤 위치에 묶을 수 있게 됐다는 점이다. 기존 CSS 애니메이션이 "2초 동안 재생"이었다면, 이제는 "스크롤이 0%에서 100%로 가는 동안 재생"이라고 적을 수 있다. 손가락이 스크롤을 멈추면 애니메이션도 그 자리에 멈춘다. 스크롤과 화면 움직임이 한 몸처럼 붙는다.

animation-timeline: scroll()

페이지 전체 스크롤에 진행도를 묶는 방식이다. 상단의 '읽은 만큼 차오르는 진행 막대'가 대표적인 예다. 요소에 animation-timeline: scroll() 한 줄을 더하면, 별도의 스크롤 계산 코드 없이 스크롤 진행에 맞춰 막대가 채워진다.

view-timeline — 화면에 들어올 때

특정 요소가 화면 안으로 들어오고 나가는 구간에 애니메이션을 묶는 방식이다. 아래로 내릴 때 이미지나 카드가 서서히 나타나는 '등장 효과'가 여기에 해당한다. 예전엔 IntersectionObserver로 요소가 보이는 순간을 감지해 클래스를 붙였다 떼야 했는데, 이제는 타임라인 지정만으로 처리된다.

작은 회사 웹사이트엔 어떻게 쓰나

화려한 연출보다 '읽는 경험을 자연스럽게 돕는' 쓰임이 어울린다.

  • 읽기 진행 막대: 소개글이나 블로그 글 상단에서 얼마나 읽었는지 보여줘 이탈을 줄인다.
  • 섹션 등장 효과: 서비스 소개 카드가 화면에 들어올 때 부드럽게 떠오르게 해 시선을 이끈다.
  • 이미지 시차(패럴럭스): 배경 사진이 본문보다 느리게 흘러 깊이감을 준다.

아직 조심할 점

편리하지만 만능은 아니다. 챙길 것이 세 가지다.

  • 브라우저 지원: 최신 크롬·엣지 계열에선 잘 돌지만, 아직 모든 브라우저가 지원하진 않는다. 애니메이션이 없어도 내용은 멀쩡히 보이도록 '없으면 그냥 정적인 화면'을 기본값으로 두는 게 안전하다.
  • 과유불급: 요소마다 움직이면 오히려 어지럽고 산만해진다. 한두 곳에만 절제해서 쓴다.
  • 접근성: 움직임에 민감한 손님을 위해 prefers-reduced-motion 설정을 존중해, 그 경우엔 애니메이션을 끄도록 한다.

정리하며

스크롤 기반 애니메이션은 '자바스크립트로 힘들게 만들던 움직임을 CSS가 가볍고 매끄럽게 대신하는' 흐름의 연장선이다. 코드가 줄면 유지보수가 쉬워지고, 브라우저가 직접 처리하니 스크롤도 덜 버벅인다. 다만 어떤 화면에 어느 정도로 쓸지, 지원되지 않는 환경까지 챙기는 판단은 여전히 사람의 몫이다. CYAN은 이런 신기술을 '멋 부리기'가 아니라 손님이 내용을 더 편하게 읽도록 돕는 도구로 절제해서 얹는다. 새 홈페이지든 리뉴얼이든, 화면에 어떤 움직임이 정말 필요한지부터 함께 짚어 드린다.