CSS animation-trigger 속성
요약
CSS의 새로운 속성인 `animation-trigger`는 특정 트리거가 발생할 때 CSS 애니메이션의 시작과 재생 방식을 제어합니다. 이 속성은 전통적으로 JavaScript와 Intersection Observer API를 사용하던 영역을 CSS 자체로 가져오며, 스크롤 기반 애니메이션의 동작을 세밀하게 정의할 수 있게 합니다.
핵심 포인트
- `animation-trigger`는 특정 트리거 발생 시 애니메이션 시작/재생 제어
- JavaScript(Intersection Observer) 의존도를 줄이고 CSS만으로 구현 가능
- 다양한 액션 키워드(`play-forwards`, `pause` 등)로 애니메이션 동작 정의
CSS의 animation-trigger
이 속성은 특정 트리거가 발생할 때까지 CSS 애니메이션의 시작을 지연시킵니다. 더 구체적으로는, 이름이 지정된 트리거를 감지하고 그에 반응하여 애니메이션이 어떻게 재생되거나 일시 정지되는지를 제어합니다.
.element {
animation: fade-in 0.35s ease-in-out both;
animation-trigger: --trigger play-forwards play-backwards;
...
}
이러한 동작은 전통적으로 JavaScript 영역이었으며, 일반적으로 Intersection Observer API를 사용했습니다.
스크롤 기반 애니메이션(Scroll-triggered animations)을 스크롤 구동 애니메이션(scroll-driven animations)과 혼동해서는 안 됩니다. 둘 다 스크롤 또는 뷰 타임라인에 의존하지만, 근본적으로 다른 개념입니다. 이 차이점은 잠시 후에 설명하겠습니다.
animation-trigger 속성은 Animation Triggers 사양에서 정의되었습니다.
구문 (Syntax)
animation-trigger: none | <트리거 이름> <진입 액션> [<종료 액션>];
초기값: none
적용 대상: 모든 요소
상속 여부: 아니요
계산된 값: 지정된 대로
애니메이션 유형: 애니메이션 불가
값 (Values)
이 속성은 none 또는 쉼표로 구분된 트리거와 해당 액션 목록을 허용합니다:
none: 기본 상태입니다. 애니메이션은 정상적으로 작동하며, 트리거에 의해 유발되는 애니메이션이 아닙니다.<트리거 이름>: 감지하고자 하는 트리거의 식별자(예:<--fade-in-trigger>)입니다. 이는timeline-trigger또는event-trigger속성에 의해 정의된 이름을 일치해야 합니다. 애니메이션이 활성화될 때(그리고 선택적으로 비활성화될 때) 애니메이션이 어떻게 작동해야 하는지를 지시하는 하나 이상의 키워드입니다. 이는 다음과 같이 더 세분화될 수 있습니다:<애니메이션 액션>: 트리거 상태가
타임라인 기반 트리거(timeline-based triggers)일 수도 있고, DOM 이벤트와 같은 이벤트 기반 트리거(event-based triggers)일 수도 있습니다 (예: 클릭). 본 항목에서는 주로 타임라인 트리거에 초점을 맞출 것입니다. 이벤트 기반 트리거가 궁금하다면 공식 명세(official spec)를 확인해 볼 수 있습니다.
기본적으로, 트리거 이름은 **전역 범위(global scope)**를 가집니다. 여러 요소가 동일한 트리거 이름을 정의하는 경우, 캐스케이드에서 나중에 오는 요소가 선택됩니다. trigger-scope 속성을 사용하여 특정 DOM 서브트리로 트리거의 범위를 제한할 수 있습니다.
애니메이션 액션 (Animation Actions)
play-forwards: 재생 속도를 양수로 설정하고 애니메이션을 재생합니다.
play-backwards: 재생 속도를 음수로 설정하고 애니메이션을 역재생합니다.
play: 현재 속도로 단순히 애니메이션을 재생합니다.
play-once: 초기 상태 또는 일시 정지된 상태에서만 애니메이션을 재생합니다. 이미 애니메이션이 끝났다면 트리거를 무시합니다.
pause: 애니메이션을 제자리에 고정(freeze)합니다.
reset: 애니메이션 진행률을 0으로 즉시 되돌리고 일시 정지합니다.
replay: 진행률을 0으로 되돌리고 즉시 재생합니다.
none: 아무것도 하지 않습니다.
일부 액션은 <enter-action> 또는 <exit-action> 전용이 아니므로, 진입할 때(entering)는 play-backwards를 사용하고 나갈 때(exiting)는 play-forwards를 사용하는 것이 가능합니다.
타임라인 트리거 (Timeline Triggers)
실제로 animation-trigger를 사용하려면, 일반적으로 먼저 타임라인 트리거를 설정해야 합니다. 이는 요소가 타임라인(스크롤 또는 뷰포트 위치와 같은) 내의 어느 지점에 있는지에 따라 애니메이션이 언제 시작될지 제어합니다. 더 구체적으로는, 해당 타임라인 내에서 정의된 활성화 범위(activation range)에 요소가 진입할 때 활성화됩니다.
타임라인 트리거를 설정하려면, 먼저 animation-trigger와 연결할 사용자 지정 <trigger-name> (예: --fade-in)을 정의하고, 이어서 view() 또는 scroll() 함수와 같은 <source> 타임라인을 정의해야 합니다.
timeline-trigger-name: --fade-in;
timeline-trigger-source: view();
그런 다음, <activation-range>를 지정합니다.
(예: contain)과 같은 속성을 사용하여 뷰포트 내에서 트리거가 정확히 언제 활성화될지 지정할 수 있습니다.
timeline-trigger-activation-range: contain;
또한, 트리거가 "꺼지기" 전에 활성 상태를 유지하는 외부 경계를 정의하기 위해 선택적 <active-range>를 제공할 수도 있지만, 이 속성을 생략하면 브라우저는 기본적으로 활성화 범위(activation range)를 사용합니다.
timeline-trigger-active-range: cover;
이것이 어떻게 작동하는지 더 잘 이해하려면 Chrome 팀의 타임라인 범위 시각화기(visualizer)를 확인해 보세요.
서로 다른 범위를 사용하는 경우, 활성 범위는 반드시 활성화 범위를 포함해야 합니다. 그렇지 않으면 트리거가 "켜질" 수 없습니다.
개별적인 모든 긴 형식 속성을 사용할 수는 있지만:
timeline-trigger-name
timeline-trigger-source
timeline-trigger-activation-range
timeline-trigger-active-range
…대신 항상 다음 축약형(shorthand)을 사용하는 것이 좋습니다:
timeline-trigger: none | <트리거 이름> <소스> <활성화 범위> [ / <활성 범위>];
많은 CSS 축약형(예: background 또는 border)과 달리, 여기서는 값의 순서가 중요하므로 자유롭게 재배열할 수 없습니다.
참고할 만한 점은 트리거와 애니메이션이 반드시 같은 요소에 있어야 하는 것은 아니라는 것입니다. 부모 요소에 timeline-trigger를 정의하고 여러 자식 요소에 animation-trigger를 적용할 수 있습니다. 부모 요소가 뷰에 진입하면 모든 자식이 함께 애니메이션될 수 있습니다.
트리거 사용하기
간단한 텍스트 노출(text reveal) 애니메이션을 만들어 보겠습니다. 우리는 요소를 **트리거 지점(trigger point)**으로 사용할 것입니다. 스크롤하여 이 지점을 지나가면 애니메이션이 재생되고 텍스트가 나타납니다.
먼저, 트리거 요소에 타임라인 트리거를 정의합니다:
.trigger {
timeline-trigger: --trigger scroll() contain / cover;
}
이 코드는 스크롤 위치를 기반으로 활성화되는 --trigger라는 이름의 트리거를 설정합니다. contain / cover 범위는 요소가 스크롤포트(scrollport)에 완전히 보이는 순간(contain) 애니메이션이 시작되며, 그 부분이 스크롤포트에 남아 있는 한 계속 실행됨을 의미합니다 (cover).
다음으로, 애니메이션을 적용할 텍스트에 animation-trigger를 그리고 실제 애니메이션 자체를 함께 적용하겠습니다:
.text {
animation-trigger: --trigger play;
animation: fade 0.6s ease-out;
...
멋진 점은 동일한 트리거를 사용하여 다양한 animation-action 값을 혼합하여 매우 다른 동작을 얻을 수 있다는 것입니다. 여기서는 다른 애니메이션 액션을 사용한 동일한 설정의 간단한 데모가 있습니다:
스크롤 기반(Scroll-Driven) vs. 스크롤 트리거 기반(Scroll-Triggered) 애니메이션
**스크롤 기반 애니메이션(scroll-driven animations)**에서는 애니메이션의 진행 상황이 스크롤 위치에 직접 연결됩니다. 스크롤함에 따라 애니메이션은 타임라인을 따라 앞으로 또는 뒤로 움직입니다. “시작”이나 “발동”이라는 개념이 없습니다.
반면에 **스크롤 트리거 기반 애니메이션(scroll-triggered animations)**은 연속적이기보다는 상태 기반입니다. 트리거는 이진 상태를 가지며, 요소가 정의된 범위에 진입하는 것과 같은 조건이 충족되면 해당 트리거는 연관된 동작(예: play, pause, 또는 reset)을 발동합니다. 일단 트리거되면 애니메이션은 스크롤 진행 상황과 연결되지 않은 일반적인 CSS 애니메이션처럼 작동합니다.
두 가지의 차이점을 확인할 수 있는 매우 멋진 데모를 utlitybend가 제공했습니다:
명세(Specification)
animation-trigger 속성은 Animation Triggers 명세에 정의되어 있으며, 현재 Editor’s Drafts 상태입니다. 이는 지금부터 공식 Candidate Recommendation으로 확정되기까지 정보가 변경될 수 있음을 의미합니다.
브라우저 지원
작성 시점 기준 Chrome 145 이상만 지원됩니다.
추가 자료(Further Reading)
- CSS Animation Triggers (utlitybend)
- CSS scroll-triggered animations (Chrome for developers)
- Scroll Triggered Animation Demos (Davmilla)
AI 자동 생성 콘텐츠
본 콘텐츠는 CSS-Tricks의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기