스크롤 애니메이션: IntersectionObserver 대신 animation-timeline
스크롤 애니메이션: IntersectionObserver 대신 animation-timeline
Scroll-driven animations는 문제를 근본에서 해결합니다. 이미 알고 있는 CSS 애니메이션과 동일하지만, 하나만 다릅니다: 시간이 진행을 구동하는 대신, 스크롤 컨테이너의 위치가 그것을 합니다. 브라우저는 컴포지터에서 실행할 수 있습니다.
4줄 진행 표시줄
css
.progress {position: fixed;inset: 0 0 auto 0;height: 4px;transform-origin: left;animation: grow linear both;animation-timeline: scroll(root block);}@keyframes grow {from { transform: scaleX(0); }to { transform: scaleX(1); }}
스크롤 시 표시: view() 타임라인
css
.reveal {animation: fade-up linear both;animation-timeline: view();animation-range: entry 0% entry 60%;}@keyframes fade-up {from { opacity: 0; transform: translateY(32px); }to { opacity: 1; transform: translateY(0); }}
4개의 이름 있는 범위: entry, exit, cover (기본값), contain.
1시간을 낭비하는 함정: animation 단축 속성이 타임라인을 초기화
css
/* 깨짐: 단축 속성이 animation-timeline을 auto로 초기화 */.reveal {animation-timeline: view();animation-range: entry 0% entry 60%;animation: fade-up linear both;}
css
/* 올바름: 단축 속성 이후에 타임라인과 범위 */.reveal {animation: fade-up linear both;animation-timeline: view();animation-range: entry 0% entry 60%;}
이름 있는 타임라인
css
.gallery {overflow-x: auto;scroll-timeline: --gallery inline;}.gallery-indicator {animation: fill linear both;animation-timeline: --gallery;timeline-scope: --gallery;}
점진적 향상은 여기서 선택 사항이 아님
css
.reveal {opacity: 1;}@supports (animation-timeline: view()) {@media (prefers-reduced-motion: no-preference) {.reveal {animation: fade-up linear both;animation-timeline: view();animation-range: entry 0% entry 60%;}}}
함정과 모범 사례
transform과opacity만 애니메이션하세요.- 애니메이션만이 드러낼 수 있는 콘텐츠를 숨기지 마세요.
- "왜 내 애니메이션이 멈춰 있지?"는 거의 항상 스크롤 컨테이너 문제입니다.
both를 fill 모드로 사용하세요.- 모션 감소는 의학적 설정이지 예의가 아닙니다.
- 여전히 필요한 JavaScript를 제거하지 마세요.
결론
Scroll-driven animations는 효과의 전체 카테고리에 메인 스레드에 대한 동일한 아이디어를 적용합니다: 스크롤 리스너, 옵저버, 클래스 변경이 필요했던 것이 하나의 CSS 속성이 됩니다.