CSS 스크롤 트리거 애니메이션이 곧 출시됩니다.

게시일: 2025년 12월 12일

2023년에는 스크롤을 통해 애니메이션을 앞으로 이동하거나 되감을 수 있는 스크롤 기반 애니메이션이 출시되었습니다. 스크롤 기반 애니메이션을 사용하면 스크롤할 때 애니메이션 진행률이 0% 에서 100% 로 진행됩니다. 스크롤을 중지하면 애니메이션이 일시중지되고, 위로 다시 스크롤하면 애니메이션이 반전됩니다.

스크롤 기반 애니메이션의 다음 장은 2026년에 시작되며, 스크롤 트리거 애니메이션이 Chrome 145에 도입됩니다. 특정 스크롤 오프셋을 교차할 때 트리거되는 시간 기반 애니메이션입니다.

이제 CSS에서 선언적으로 이 유형의 효과를 적용할 수 있으므로 IntersectionObserver는 사용하지 않아도 됩니다.

타임라인 트리거, 애니메이션 트리거, 작업

애니메이션 트리거

CSS에서 스크롤 트리거 애니메이션을 설정하려면 요소에 연결된 일반 CSS 애니메이션으로 시작하세요.

animation: unclip 0.35s ease-in-out both;

이 애니메이션은 DocumentTimeline를 드라이버로 사용하며 0.35초 동안 실행됩니다. 애니메이션은 페이지 로드 후 자동으로 트리거됩니다. 트리거를 변경하려면 새 animation-trigger CSS 속성을 사용하세요.

animation-trigger: --t play-forwards play-backwards;

여기서는 애니메이션이 트리거 --t에 의해 트리거되도록 설정되어 있습니다. 이 트리거가 활성화되면 애니메이션에서 play-forwards 작업이 호출되고 트리거가 비활성화되면 play-backwards 작업이 호출됩니다.

사양에는 전체 작업 목록이 포함되어 있습니다.

트리거 만들기

하지만 --t 트리거는 무엇일까요? 이름이 --t인 트리거입니다. 특히 스크롤 트리거 애니메이션의 경우 스크롤 진행률 타임라인 또는 뷰 진행률 타임라인을 소스로 사용하는 '타임라인 트리거'입니다.

타임라인 트리거를 정의하려면 timeline-trigger 속성 (또는 관련 긴 형식)을 사용합니다. 예를 들어 뷰 타임라인을 소스로 사용하는 --t라는 트리거를 만들려면 다음을 사용합니다.

timeline-trigger-name: --t;
timeline-trigger-source: view();

이렇게 생성된 트리거 --t는 일치하는 요소와 연결된 뷰 타임라인에 따라 활성화 및 비활성화됩니다. 뷰 타임라인의 기본 범위는 cover 범위이므로 트리거는 해당 범위 내에 있거나 벗어날 때도 활성화 및 비활성화됩니다.

트리거 범위 조정

트리거가 활성 또는 비활성 상태여야 하는 시점의 위치를 조정하려면 트리거에서 활성화 및 활성 범위를 지정하세요. 다음 예에서 활성화 범위는 entry 100% exit 0%로 설정되어 있습니다. 즉, 피사체가 이 범위 내에 있으면 트리거가 활성화됩니다.

timeline-trigger:
  --t
  view()
  entry 100% exit 0%
;

위 스니펫에는 활성 범위가 지정되어 있지 않으므로 활성화 범위가 활성 범위로도 사용됩니다. 활성 범위를 벗어나면 트리거가 비활성화됩니다.

이미 정의된 animation-trigger와 결합하면 대상이 스크롤 포트에 완전히 들어갔을 때 애니메이션이 앞으로 재생되고 스크롤 포트를 벗어나기 직전에는 애니메이션이 뒤로 재생됩니다.

트리거 범위가 entry 100% exit 0%로 설정된 데모 녹화.데모에는 범위의 시작과 끝을 나타내는 디버그 선도 표시됩니다.

활성화 범위와 활성 범위가 다를 수 있습니다. 예를 들면 다음과 같습니다.

timeline-trigger:
  --t
  view()
  entry 100% exit 0% / entry 0% exit 100%
;

여기서 주제가 entry 100% exit 0% 범위에 있으면 트리거가 활성화됩니다. 트리거는 entry 0% exit 100% 범위를 벗어날 때까지 활성 상태로 유지됩니다.

이렇게 하면 대상이 스크롤 포트에 들어갈 때 애니메이션이 앞으로 재생되며, 이전과 달리 대상이 스크롤 포트를 완전히 벗어날 때까지 활성 상태로 유지됩니다.

트리거 범위가 entry 100% exit 0% / entry 0% exit 100%로 설정된 데모 녹화 영상입니다.
데모에는 범위의 시작과 끝을 나타내는 디버그 선도 표시됩니다. 활성 범위가 스크롤 포트를 둘러싸고 있으므로 디버그 선이 표시되지 않습니다.

트리거 범위 제한

트리거는 전역적으로 표시되므로 특정 이름의 트리거를 선언하는 마지막 일치가 '승리'합니다. 트리거의 공개 범위를 제한하려면 trigger-scope 속성을 사용하세요. 이는 anchor-scope를 사용하는 방법과 유사합니다.

trigger-scope: --t; /* List of dashed idents, or `all` */

트리거를 선언하고 여러 요소와 일치하는 CSS 규칙이 있는 경우 trigger-scope를 사용해야 합니다.

데모

다음 데모에서는 양식이 다양한 전체 높이 섹션에 걸쳐 분할됩니다. 양식의 각 부분이 표시되면 스크롤 트리거 애니메이션을 사용하여 애니메이션이 적용됩니다. 스크롤 포트를 벗어나면 애니메이션이 적용되어 사라집니다.

이 경우 스크롤 트리거 애니메이션 로직은 다음과 같습니다.

@keyframes card {
  from { translate: 0 -50% 0; }
}

@keyframes card-contents {
  from { opacity: 0; height: 0px; }
  to { opacity: 1; height: auto; }
}

.card {
  overflow-y: clip; /* Hide any overflow in the y-axis */

  timeline-trigger:
    --t
    view()
    contain 15% contain 85% / entry 100% exit 0%
  ;
  trigger-scope: --t;

  animation: unclip var(--duration) ease-in-out both;
  animation-trigger: --t play-forwards play-backwards;
}

.card > * {
  interpolate-size: allow-keywords; /* To animate to `height: auto` */

  animation: card-contents var(--duration) ease-in-out both;
  animation-trigger: --t play-forwards play-backwards;
}

코드를 분석하면 다음과 같습니다.

  • timeline-trigger의 이름은 --t이며 소스는 일치하는 요소를 추적하는 뷰 타임라인으로 설정됩니다.
  • 트리거의 활성화 범위는 contain 15% contain 85%입니다. 피사체가 해당 범위 내에 있으면 트리거가 활성화됩니다.
  • 활성화되면 피사체가 entry 100% exit 0%의 활성 범위에 있는 동안 트리거가 활성 상태로 유지됩니다.
  • unclip 애니메이션이 요소에 연결됩니다.
  • 애니메이션이 --t를 트리거 소스로 사용하도록 설정되어 있습니다. 트리거가 활성화되면 애니메이션이 앞으로 재생되기 시작합니다.
  • 피사체가 활성 범위를 벗어나 트리거가 비활성화되면 애니메이션이 역방향으로 재생됩니다.
  • 카드 콘텐츠도 동일한 트리거 --t를 사용하여 애니메이션으로 표시되고 사라집니다.

이 예시에는 timeline-trigger를 지원하지 않는 브라우저를 위해 IntersectionObserver를 사용하는 대체가 포함되어 있습니다.

더 많은 데모

스크롤 트리거 애니메이션을 충분히 사용하지 못하는 경우 다음 데모를 확인하세요.

Meet the monsters' 데모 녹화 영상

의견

이 기능을 계속 개선하기 위해 의견을 기다리고 있습니다. 소셜 미디어로 문의하거나 CSS 작업 그룹에 문제를 신고하여 의견을 남겨 주세요.

버그가 발생하면 Chromium 버그를 신고하여 알려주세요. 알려진 버그 목록은 Chromium 버그 추적기를 참고하세요.