CSS animation-timeline: scroll()로 JS 없이 스크롤 애니메이션 만들기
문제
페이지 스크롤에 따라 상단에 진행률 바를 보여주고 싶은데, 보통 scroll 이벤트 리스너 달고 requestAnimationFrame으로 처리한다. 근데 이거 성능도 신경 써야 하고 코드도 길어진다.
해결
CSS animation-timeline: scroll()을 쓰면 JS가 필요 없다.
/* 스크롤 진행률 바 */
.progress-bar {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: #3b82f6;
transform-origin: left;
animation: grow-progress linear;
animation-timeline: scroll();
}
@keyframes grow-progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
<div class="progress-bar"></div>
이게 전부다. animation-timeline: scroll()이 시간 기반 대신 스크롤 위치 기반으로 애니메이션을 구동시킨다.
특정 요소가 뷰포트에 들어올 때 애니메이션을 주고 싶으면 view()를 쓴다.
.fade-in {
animation: fade-in linear;
animation-timeline: view();
animation-range: entry 0% cover 40%;
}
@keyframes fade-in {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
animation-range로 애니메이션이 시작/끝나는 구간을 세밀하게 조절할 수 있다. entry, exit, cover, contain 같은 키워드를 조합하면 된다.
핵심 포인트
animation-timeline: scroll()은 스크롤 위치 기반 애니메이션, JS 불필요view()는 요소의 뷰포트 진입/이탈 기반 애니메이션animation-range로 애니메이션 구간을 정밀하게 제어 가능transform과opacity만 쓰면 컴포지터 스레드에서 돌아서 60fps 보장- Chrome, Edge, Safari 18+ 지원. Firefox는 아직 플래그 뒤에 있다