clip-path및mask-image를 사용하여 맞춤 기하학적 표시 및 부드러운 페이드 아웃을 구현합니다.- JS 리스너 대신 스크롤 기반 애니메이션 (
animation-timeline: scroll())을 사용하여 필수적이지 않은 스크롤 기반 효과를 구현합니다. - 뷰 전환을 사용하여 복잡한 레이아웃 상태 간에 원활하게 애니메이션을 적용합니다.
성능
- 애니메이션이 컴포지터 스레드에 유지되도록
opacity및transform(개별 변환 속성 포함, 예:left/right/top/bottom대신translate)에 애니메이션을 적용하는 것이 좋습니다. transition-behavior: allow-discrete,@starting-style, (<dialog>또는[popover]와 같은 최상위 요소의 경우)overlay를 사용하여 개별 시작 및 종료 상태를 기본적으로 애니메이션 처리합니다. 요소 시작 및 종료 애니메이션 처리 및 최상위 요소 애니메이션 처리를 참고하세요.
.popover-reveal {
/* Transition discrete display and top-layer overlay alongside opacity */
transition:
opacity ease-out,
display,
overlay;
transition-duration: 0.2s;
transition-behavior: allow-discrete;
}
접근성
prefers-reduced-motion 미디어 쿼리를 사용하여 모션이 많은 것을 선호하지 않는 사용자를 위해 모션을 사용 중지합니다.
- 일시중지 메커니즘 제공: 사용자가 자동 실행 캐러셀, 배너 또는 기타 지속적인 애니메이션을 중지할 수 있도록 합니다.
- 정적 뷰를 기본값으로 설정: 정적 상태를 기본값으로 설정하고 사용자가 모션을 선택할 수 있도록 하는 것이 좋습니다.
- 깜박임 한도 (초당 3회)를 초과하지 않기: 밝은 빛과 어두운 빛이 빠르게 깜박이는 콘텐츠를 포함하지 않습니다. 이러한 효과는 발작을 일으킬 수 있습니다.
animation-duration: 0.01ms;를 전역적으로 적용하지 마세요. 특정 애니메이션이 더 거슬릴 수 있습니다.
대신 @media 쿼리를 규칙 내에 중첩하여 두 버전이 함께 유지되도록 하는 두 가지 접근 방식 중 하나를 사용하여 사례별로 모션 환경설정을 처리합니다.
- 기본적으로 애니메이션을 사용 설정한 상태에서 시작하고
@media (prefers-reduced-motion: reduce)를 사용하여 애니메이션을 줄입니다.
/* Good: Dampen spin states or slow down animations for reduced motion */
.spinner {
animation: spin 1s linear infinite;
@media (prefers-reduced-motion: reduce) {
animation: none;
opacity: 0.5;
}
}
progress:not([value]) {
animation: slide 1s infinite linear;
@media (prefers-reduced-motion: reduce) {
animation-duration: 20s;
}
}
- 기본적으로 애니메이션 없이 시작하고
@media (prefers-reduced-motion: no-preference)를 사용하여 애니메이션을 사용 설정합니다.
/* Good: Default to static or gentle states and opt-in to full motion */
.spinner {
opacity: 0.5;
@media (prefers-reduced-motion: no-preference) {
opacity: 1;
animation: spin 1s linear infinite;
}
}
progress:not([value]) {
animation: slide 20s infinite linear;
@media (prefers-reduced-motion: no-preference) {
animation-duration: 1s;
}
}
JavaScript에서 애니메이션 및 전환 이벤트 사용하기
AnimationEvent (animationstart, animationiteration, animationend, animationcancel) 및 TransitionEvent (transitionrun, transitionstart, transitionend, transitioncancel) 인터페이스 모두에서 event.target는 원래 DOM 요소를 제공합니다. 이벤트를 트리거한 특정 Animation 객체 (Animation, CSSAnimation 또는 CSSTransition)에 액세스하려면 읽기 전용 event.animation 속성을 사용합니다.
event.animation를 사용할 수 없는 경우 일반적으로 event.target.getAnimations()를 호출하고 event.animationName (또는 전환의 경우 event.propertyName)로 필터링하여 Animation 인스턴스를 찾을 수 있습니다. 하지만 event.target.getAnimations()를 필터링하는 이 대체가 예상대로 작동하지 않는 여러 시나리오를 방지하려면 event.animation를 직접 사용하는 것이 좋습니다.
- Web Animations API (
element.animate()) 애니메이션에는animationName가 없으므로event.target.getAnimations()를 필터링할 때 이름으로 일치시킬 수 없습니다. - 이름이 같은 여러 애니메이션이 동일한 요소에 연결된 경우
AnimationEvent의animationName로 필터링하면 모호해집니다.TransitionEvent의transitionProperty에 대한 필터링은 전환 속성당 하나의 이벤트만 있으므로 작동합니다.
event.target는 항상 원래 DOM 요소를 가리키므로 요소 자체에서 실행되는 애니메이션과 의사 요소 중 하나에서 실행되는 애니메이션을 구분하지 않습니다. 반면event.animation.effect.pseudoElement는 타겟 의사 요소를 직접 노출합니다.
// Works in most basic CSS animation cases, but fails for WAAPI animations,
// duplicate animation names on the same element, or pseudo-elements.
document.addEventListener('animationstart', (event) => {
const animation = event.target
.getAnimations()
.find((anim) => anim.animationName === event.animationName);
console.log(animation);
});
// PREFERRED: Directly access the exact Animation object via event.animation
document.addEventListener('animationstart', (event) => {
const animation = event.animation;
console.log(animation);
});
'animation' in AnimationEvent.prototype (또는 'animation' in TransitionEvent.prototype)를 사용하여 지원을 기능 감지할 수 있습니다.