# Advanced Interactions with CSS Animation Triggers

How to control scroll and viewport-based animations without JavaScript

- **Source:** [CSS-Tricks](https://brifing.si/source/eea3b580-b2ba-4369-b9e0-7fc8ad2ad5e3)
- **Published:** 2026-08-26
- **Topic:** [Software & Engineering](https://brifing.si/c/engineering)
- **Original article:** <https://css-tricks.com/almanac/properties/a/animation-trigger/>
- **On Brifing:** https://brifing.si/s/4ee69cae-b36d-4192-a6d9-b30d4b1f2337

## What is animation-trigger?

The CSS animation-trigger property delays animation playback until a specific trigger (scroll, viewport position or DOM event) occurs. For example, you can start a fade-in animation when an element enters the viewport. Traditionally implemented with Intersection Observer API in JavaScript, this functionality is now natively supported in CSS. Simple syntax: animation-trigger: --trigger-name action. Currently experimental in Chrome 115+ and Safari TP.

## Trigger types

Two main trigger types exist: Timeline-based (scroll/view progress) and event-based (click/hover). Scroll-triggered animations start/stop based on element's viewport position. For example, timeline-trigger-source: scroll() tracks scroll position. Event-based triggers respond to user interactions. Currently, timeline-based triggers are more commonly used in production.

## Activation ranges

timeline-trigger-activation-range defines when animation triggers based on viewport position. 'contain' triggers when element is fully visible; 'cover' when partially visible. Example: timeline-trigger: --fade-in scroll() contain/cover starts animation when element fully enters viewport and continues until it partially exits. These ranges are crucial for responsive designs.

## Animation actions

Eight different actions supported: play-forwards, play-backwards, pause, reset etc. For example, animation-trigger: --menu-anim play-once makes menu animation play only once. Separate enter/exit actions (e.g., play-backwards when exiting) enable sophisticated transitions. The 'replay' action resets progress to 0 and plays immediately.

## Trigger scope management

trigger-scope property limits trigger's scope. By default trigger names work globally, but can be scoped to specific DOM subtrees. Prevents conflicts in complex components. Example: .sidebar { trigger-scope: --sidebar-anim; } controls animations only within sidebar. Cascade order determines which trigger applies when duplicates exist.

## Scroll-driven vs scroll-triggered

Scroll-driven animations (continuously synced with scroll position) differ from scroll-triggered (binary state-based). In scroll-driven, animation progresses continuously with scroll; in triggered version, animation starts/stops at specific thresholds. Example: a chart can continuously rotate with scroll (driven) or fade-in at certain point (triggered).

## Parent-child synchronization

Define trigger on parent element and apply animations to children for synchronized animation groups. Example: when .hero section enters viewport, its heading, subheading and buttons can animate sequentially. This pattern is ideal for micro-interactions and provides performance benefits by reducing DOM operations.

## Future and limitations

Animation Triggers spec is currently in Editor's Draft stage. Experimental support in Chrome 115+ and Safari TP. While not as flexible as JavaScript, it covers ~80% of use cases. Key advantages: performance (runs off main thread) and maintainability (stays in CSS). Expected to gain popularity for LCP element entry animations soon. Fallbacks needed for unsupported browsers.

## Sources covering this story

- https://css-tricks.com/almanac/properties/a/animation-trigger/ — 

---

_Summary written by Brifing from the original reporting. Copyright in the original article belongs to its publisher; read the full piece at the link above._
