timeline-trigger CSS property

Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

The timeline-trigger CSS shorthand property defines a scroll-triggered animation trigger on an element.

Constituent properties

This property is a shorthand for the following CSS properties:

Syntax

css
/* Keyword */
timeline-trigger: none;

/* name | source */
timeline-trigger: --t view();
timeline-trigger: --t --my-timeline;

/* name | source | activation range */
timeline-trigger: --t view() contain;
timeline-trigger: --t view() entry exit 50%;

/* name | source | activation range | active range */
timeline-trigger: --t view() contain / cover;
timeline-trigger: --t view() entry / entry exit 50%;

/* Multiple triggers */
timeline-trigger:
  --t view(),
  --other-trigger --my-timeline entry / entry 50% exit 50%;

/* Global values */
timeline-trigger: inherit;
timeline-trigger: initial;
timeline-trigger: revert;
timeline-trigger: revert-layer;
timeline-trigger: unset;

Values

Specified as a space-separated list of the constituent timeline trigger property values, or the keyword none.

none

Specifies that the element does not create a trigger, resetting all four longhand properties to their default values.

<'timeline-trigger-name'>

A timeline-trigger-name value representing the trigger's identifying name. Defaults to none.

<'timeline-trigger-source'>

A timeline-trigger-source value representing the trigger's timeline. Defaults to auto.

<'timeline-trigger-activation-range'> Optional

A timeline-trigger-activation-range value representing the trigger's activation range. Defaults to normal, which is equivalent to cover 0% cover 100% for a view progress timeline timeline-trigger-source, and 0% 100% for a scroll progress timeline timeline-trigger-source.

<'timeline-trigger-active-range'> Optional

A timeline-trigger-active-range value representing the trigger's activation range. Defaults to auto, which sets the <'timeline-trigger-active-range'> to the same value as the <'timeline-trigger-activation-range'>.

Description

The timeline-trigger property can be used to define all the longhand properties used to create a CSS scroll-triggered animation trigger in a single declaration, resetting those not explicitly set.

A typical example looks like so:

css
.trigger {
  timeline-trigger: --my-trigger view() entry / contain;
}

An element with this declaration set will have:

  • An identifying timeline-trigger-name of --my-trigger.
  • A timeline-trigger-source value of view(), which selects the element's nearest ancestor scrolling element to define its timeline trigger.
  • An activation range of entry, meaning that the trigger will activate when its tracked element moves into the entry range. This is the range between the element's start edge crossing the scrollport's end edge, and the element's end edge crossing the scrollport's end edge.
  • An active range of contain meaning that once activated, the trigger will stay active until its tracked element leaves the contain range: the range in which any part of the tracked element is visible in the scrollport.

An animated element can be triggered by the previously-described trigger by referencing its identifying name in its animation-trigger property. It is possible for the animated element and the element that creates the trigger to be the same element; that is, if a single element has both the timeline-triggerand animation-trigger properties set on it.

The none value

The none keyword specifies that the element does not create a scroll-triggered animation trigger. none is equivalent to setting none auto normal / normal, which effectively resets all four equivalent longhand properties to their default values.

Shorthand property order

Due to the potential for ambiguities in the syntax, this shorthand's values must be given in the specified order.

The timeline-trigger-active-range value can only be included if the timeline-trigger-activation-range value is included.

Formal definition

Initial valueas each of the properties of the shorthand:
Applies toall elements
Inheritedno
Computed valueas each of the properties of the shorthand:
Animation typeas each of the properties of the shorthand:

Formal syntax

timeline-trigger = 
none |
[ <'timeline-trigger-name'> <'timeline-trigger-source'> <'timeline-trigger-activation-range'> [ / <'timeline-trigger-active-range'> ]? ]#

<timeline-trigger-name> =
none |
<dashed-ident>#

<timeline-trigger-source> =
<single-animation-timeline>#

<timeline-trigger-activation-range> =
[ <'timeline-trigger-activation-range-start'> <'timeline-trigger-activation-range-end'>? ]#

<timeline-trigger-active-range> =
[ <'timeline-trigger-active-range-start'> <'timeline-trigger-active-range-end'>? ]#

<single-animation-timeline> =
auto |
none |
<dashed-ident> |
<scroll()> |
<view()>

<timeline-trigger-activation-range-start> =
[ normal | <length-percentage> | <timeline-range-name> <length-percentage>? ]#

<timeline-trigger-activation-range-end> =
[ normal | <length-percentage> | <timeline-range-name> <length-percentage>? ]#

<timeline-trigger-active-range-start> =
[ auto | normal | <length-percentage> | <timeline-range-name> <length-percentage>? ]#

<timeline-trigger-active-range-end> =
[ auto | normal | <length-percentage> | <timeline-range-name> <length-percentage>? ]#

<scroll()> =
scroll( [ <scroller> || <axis> ]? )

<view()> =
view( [ <axis> || <'view-timeline-inset'> ]? )

<length-percentage> =
<length> |
<percentage>

<scroller> =
root |
nearest |
self

<axis> =
block |
inline |
x |
y

<view-timeline-inset> =
[ [ auto | <length-percentage> ]{1,2} ]#

Examples

Basic usage

In this example, we show how to set up a basic scroll-triggered animation, including defining the trigger using a timeline-trigger shorthand property.

HTML

Our markup contains two <div> elements, one to animate and one on which to create a trigger, and some basic text content to cause the page to scroll.

We have hidden the text content for brevity.

html
<div class="animated">I am animated</div>

...

<div class="trigger">I create the trigger</div>

...

CSS

The animated <div> element's position is set to fixed, positioning it near the top-left of the scrollport to enable us to see when its animation starts and stops.

css
.animated {
  position: fixed;
  top: 25px;
  left: 25px;
}

Next, we define the @keyframes for the rotate animation we will use later:

css
@keyframes rotate {
  from {
    rotate: 0deg;
  }

  to {
    rotate: 360deg;
  }
}

Using the animation shorthand, the .animated element has the rotate animation applied. Without an associated trigger, the element would start animating when the page loads. The animation-trigger property makes it a triggered animation. The value references a timeline-trigger-name of --t and specifies two <animation-action> values — play and pause — which specify that the animation will play on activation, and pause on deactivation.

css
.animated {
  animation: rotate 3s infinite linear;
  animation-trigger: --t play pause;
}

The .trigger <div> element creates the animated <div>'s trigger using a timeline-trigger value of --t view() entry / cover. This specifies the following, all in a single declaration:

  • A timeline-trigger-name value of --t, which is equal to the identifier referenced in the animated <div>'s animation-trigger property value, associating the two together.
  • A timeline-trigger-source value of view(), which sets the timeline trigger as a view progress timeline, and the element providing the timeline trigger as the nearest scrolling ancestor element.
  • A timeline-trigger-activation-range of entry, which means that the trigger will activate in the entry range (from the point where the tracked element's block start edge enters the scrollport, to the point where its block end edge enters the scrollport).
  • A timeline-trigger-active-range of cover, which means that, once activated, the trigger will stay active until the tracked element leaves the cover range (in other words, until it completely leaves the scrollport).
css
.trigger {
  timeline-trigger: --t view() entry / cover;
}

Result

Try scrolling the content. The rotation will start when the tracked element enters the entry range down the bottom of the scrollport, but won't stop again until it has completely exited the scrollport.

Multiple timeline-trigger values

In this example, we build on the previous example to demonstrate how multiple timeline-trigger values can be set on the same element, creating multiple triggers that can be used to trigger multiple animations.

HTML

The markup for this example is exactly the same as the previous example markup except that we have included one extra animated <div> element with a class of animated2. This example has a total of two animated elements and one element to create triggers on.

CSS

We give the animated elements fixed positioning like in the previous example, but we give them different left values so that they don't sit on top of one another.

css
.animated,
.animated2 {
  position: fixed;
  top: 25px;
}

.animated {
  left: 25px;
}

.animated2 {
  left: 150px;
}

Next, we define the @keyframes for the two animations we'll apply to the <div>s:

css
@keyframes rotate {
  from {
    rotate: 0deg;
  }

  to {
    rotate: 360deg;
  }
}

@keyframes up-down {
  0% {
    translate: 0 0;
  }

  25% {
    translate: 0 25px;
  }

  50% {
    translate: 0 0;
  }

  75% {
    translate: 0 -25px;
  }

  100% {
    translate: 0 0;
  }
}

The scroll trigger CSS is very similar to the previous example, except that in this case we have separate animation and animation-trigger properties applied to the two animated <div> elements. Each one has a different animation that is triggered by a separate timeline trigger, and different <animation-action> values applied. The first animation plays on activation and plays in reverse on deactivation, whereas the second one plays on activation and pauses on deactivation.

css
.animated {
  animation: rotate 3s infinite linear both;
  animation-trigger: --t play-forwards play-backwards;
}

.animated2 {
  animation: up-down 1s infinite linear;
  animation-trigger: --t2 play pause;
}

We then set a timeline-trigger value on the .trigger <div> that contains two separate values. Each one has a separate timeline-trigger-name and different timeline-trigger-activation-range and timeline-trigger-active-range values so that the two animated elements start and stop their animations at different offsets.

css
.trigger {
  timeline-trigger:
    --t view() entry / cover,
    --t2 view() contain;
}

Result

Try scrolling the content. The first animated element will start to rotate when the tracked element enters the entry range down at the bottom of the scrollport, and will start to rotate in reverse when the tracked element has completely exited the scrollport. The second animated element will start to move up and down when the tracked element has completely entered the scrollport, and stop when it starts to exit again.

Specifications

Specification
Animation Triggers
# propdef-timeline-trigger

Browser compatibility

See also