English

A comprehensive guide to CSS Scroll Timelines, a powerful new web animation technique that links animations directly to scroll position. Learn how to create engaging and interactive user experiences.

CSS Scroll Timeline: Animating Based on Scroll Position

Scroll-driven animations are revolutionizing web design, offering engaging and interactive user experiences that go beyond traditional static layouts. CSS Scroll Timelines provide a native browser solution for creating these animations, directly linking animation progress to the scroll position of an element. This opens up a world of creative possibilities for enhancing user engagement and storytelling on the web.

What are CSS Scroll Timelines?

CSS Scroll Timelines allow you to control the progress of a CSS animation or transition based on the scroll position of a specified scroll container. Instead of relying on traditional time-based animations, where the animation duration is fixed, the animation progress is directly tied to how far a user has scrolled. This means the animation will pause, play, rewind, or fast-forward in direct response to the user's scrolling behavior, creating a more natural and interactive experience. Imagine a progress bar that fills as you scroll down a page, or elements that fade in and out as they enter the viewport – these are the kinds of effects that are easily achievable with CSS Scroll Timelines.

Why Use CSS Scroll Timelines?

Key Concepts and Properties

Understanding the core concepts and CSS properties is crucial for effectively utilizing Scroll Timelines:

1. Scroll Timeline

The scroll-timeline property defines the scroll container to be used as the timeline for the animation. You can specify a named timeline (e.g., --my-scroll-timeline) or use predefined values like auto (the nearest ancestor scroll container), none (no scroll timeline), or root (the document's viewport).

/* Define a named scroll timeline */
.scroll-container {
  scroll-timeline: --my-scroll-timeline;
}

/* Use the named timeline in the animation */
.animated-element {
  animation-timeline: --my-scroll-timeline;
}

2. Animation Timeline

The animation-timeline property assigns a scroll timeline to an animation. This property links the animation's progress to the scroll position of the specified scroll container. You can also use the view() function which creates a timeline based on an element intersecting with the viewport.

/* Link the animation to the scroll timeline */
.animated-element {
  animation-timeline: --my-scroll-timeline;
}

/* Use view() for viewport-based animations */
.animated-element {
  animation-timeline: view();
}

3. Scroll Offsets

Scroll offsets define the start and end points of the scroll timeline that correspond to the beginning and end of the animation. These offsets allow you to control precisely when the animation starts and stops based on the scroll position. You can use keywords like cover, contain, entry, exit, and numeric values (e.g., 100px, 50%) to define these offsets.

/* Animate when the element is fully visible */
.animated-element {
  scroll-timeline-axis: block;
  animation-timeline: view(block);
  animation-range: entry 0% cover 100%;
}

/* Start animation 100px from the top, end when bottom is 200px from viewport bottom */
.animated-element {
  scroll-timeline-axis: block;
  animation-timeline: view(block);
  animation-range: 100px exit 200px;
}

4. Scroll Timeline Axis

The scroll-timeline-axis property specifies the axis along which the scroll timeline progresses. It can be set to block (vertical scrolling), inline (horizontal scrolling), both (both axes), or auto (determined by the browser). When using `view()`, it's recommended to specify the axis explicitly.

/* Define the scroll timeline axis */
.scroll-container {
  scroll-timeline-axis: y;
}

/* With view */
.animated-element {
  scroll-timeline-axis: block;
}

5. Animation Range

The `animation-range` property defines the scroll offsets (start and end points) that correspond to the animation's beginning (0%) and end (100%). This allows you to map specific scroll positions to the animation's progress.

/* Map the entire scroll range to the animation */
.animated-element {
  animation-range: entry 0% cover 100%;
}

/* Start the animation halfway through the scroll range */
.animated-element {
  animation-range: 50% 100%;
}

/* Use pixel values */
.animated-element {
  animation-range: 100px 500px;
}

Practical Examples and Use Cases

Let's explore some practical examples of how to use CSS Scroll Timelines to create engaging animations:

1. Progress Bar

A classic use case for scroll-driven animations is a progress bar that fills as the user scrolls down the page. This provides visual feedback on how far the user has progressed through the content.

/* CSS */
.progress-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 5px;
  background-color: #eee;
  z-index: 1000;
}

.progress-bar {
  height: 5px;
  background-color: #4CAF50;
  width: 0%;
  animation: fillProgressBar linear;
  animation-timeline: view();
  animation-range: entry 0% cover 100%;
  transform-origin: 0%;
  animation-fill-mode: forwards;
}

@keyframes fillProgressBar {
  to {
    width: 100%;
  }
}

/* HTML */
<div class="progress-container">
  <div class="progress-bar"></div>
</div>
<div class="content">
  <p>... your content here ...</p>
</div>

This code creates a fixed progress bar at the top of the page. The fillProgressBar animation gradually increases the width of the progress bar from 0% to 100% as the user scrolls down the page. The animation-timeline: view() links the animation to the viewport's scroll progress, and `animation-range` ties the scrolling to the visual progress.

2. Image Fade-In

You can use Scroll Timelines to create a subtle fade-in effect for images as they enter the viewport, enhancing the visual appeal of your content.

/* CSS */
.fade-in-image {
  opacity: 0;
  transform: translateY(20px);
  animation: fadeIn linear;
  animation-timeline: view();
  animation-range: entry 25% cover 75%;
  animation-fill-mode: both;
}

@keyframes fadeIn {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* HTML */
<img src="image.jpg" class="fade-in-image" alt="Image">

This code initially hides the image and positions it slightly below its final position. As the image scrolls into view, the fadeIn animation gradually increases the opacity and moves the image to its original position, creating a smooth fade-in effect. The `animation-range` specifies that the animation starts when the image's top edge is 25% into the viewport and completes when the bottom edge is 75% into the viewport.

3. Sticky Elements

Achieve "sticky" effects – where elements stick to the top of the viewport during scrolling – but with enhanced control and transitions. Imagine a navigation bar that smoothly morphs into a condensed version as the user scrolls down.

/*CSS*/
.sticky-container {
  height: 200px; /* Adjust to your needs */
  position: relative;
}

.sticky-element {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  background-color: #f0f0f0;
  padding: 20px;
  box-sizing: border-box;
  animation: stickyAnimation linear;
  animation-timeline: view();
  animation-range: entry 0% cover 20%; /* Adjust range as needed */
  animation-fill-mode: both;
  z-index: 10;
}

@keyframes stickyAnimation {
  0% {
    position: absolute;
    top: 0;
  }
  100% {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    background-color: #ddd; /* Change color to indicate stickiness */
  }
}

/* HTML */
<div class="sticky-container">
  <div class="sticky-element">My Sticky Element</div>
</div>

In this example, the element transitions from `position: absolute` to `position: fixed` as it enters the top 20% of the viewport, creating a smooth "sticking" effect. Adjust the `animation-range` and CSS properties within the keyframes to customize the behavior.

4. Parallax Scrolling Effect

Create a parallax scrolling effect where different layers of content move at different speeds as the user scrolls, adding depth and visual interest to the page.

/* CSS */
.parallax-container {
  position: relative;
  height: 500px; /* Adjust to your needs */
  overflow: hidden;
}

.parallax-layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-size: cover;
  background-position: center;
}

.parallax-layer--bg {
  background-image: url("background.jpg");
  animation: parallaxBg linear;
  animation-timeline: view();
  animation-range: entry 0% cover 100%;
  transform-origin: 50% 0%;
  animation-fill-mode: both;
}

.parallax-layer--fg {
 background-image: url("foreground.png");
  animation: parallaxFg linear;
  animation-timeline: view();
  animation-range: entry 0% cover 100%;
  transform-origin: 50% 0%;
  animation-fill-mode: both;
}

@keyframes parallaxBg {
 to {
    transform: translateY(50px); /* Adjust for parallax speed */
 }
}

@keyframes parallaxFg {
 to {
   transform: translateY(100px); /* Adjust for parallax speed */
 }
}

/* HTML */
<div class="parallax-container">
  <div class="parallax-layer parallax-layer--bg"></div>
  <div class="parallax-layer parallax-layer--fg"></div>
</div>

This example creates two layers with different background images. The `parallaxBg` and `parallaxFg` animations translate the layers at different speeds, creating the parallax effect. Adjust the `translateY` values in the keyframes to control the speed of each layer.

5. Text Reveal Animation

Reveal text character by character as the user scrolls past a certain point, drawing attention and enhancing the storytelling aspect of the content.

/* CSS */
.text-reveal-container {
  position: relative;
  overflow: hidden;
}

.text-reveal {
  display: inline-block;
  white-space: nowrap;
  overflow: hidden;
  animation: textRevealAnimation steps(1) forwards;
  animation-timeline: view();
  animation-range: entry 25% cover 75%;
  animation-fill-mode: both;
  width: 0;
}

@keyframes textRevealAnimation {
  to {
    width: 100%;
  }
}

/* HTML */
<div class="text-reveal-container">
  <span class="text-reveal">This text will be revealed as you scroll.</span>
</div>

This example utilizes the `steps(1)` timing function to reveal the text character by character. The `width: 0` initially hides the text, and the `textRevealAnimation` gradually increases the width to reveal the entire text. Adjust the `animation-range` to control when the text reveal animation starts and ends.

Browser Compatibility and Polyfills

CSS Scroll Timelines are a relatively new technology, and browser support is still evolving. As of late 2023, major browsers like Chrome and Edge offer good support. Firefox and Safari are actively working on implementing the feature. It's essential to check the current browser compatibility before implementing Scroll Timelines in production. You can use resources like Can I use to verify the support status.

For browsers that don't natively support Scroll Timelines, you can use polyfills to provide similar functionality. A polyfill is a piece of JavaScript code that implements the missing feature using JavaScript. Several polyfills are available for CSS Scroll Timelines, allowing you to use the feature even in older browsers.

Accessibility Considerations

While scroll-driven animations can enhance the user experience, it's crucial to consider accessibility to ensure your website is usable by everyone, including users with disabilities.

Best Practices and Tips

Here are some best practices and tips for using CSS Scroll Timelines effectively:

Global Considerations for Animation Design

When designing animations for a global audience, keep these points in mind:

Conclusion

CSS Scroll Timelines offer a powerful and efficient way to create engaging and interactive web animations. By linking animation progress to the scroll position, you can create experiences that are more dynamic, responsive, and user-friendly. While browser support is still evolving, the benefits of using CSS Scroll Timelines – improved performance, a declarative approach, and enhanced user experience – make them a valuable tool for modern web developers. As you experiment with Scroll Timelines, remember to prioritize accessibility and consider the global context of your audience to create truly inclusive and engaging web experiences.

Embrace this exciting new technology and unlock a world of creative possibilities for your web projects. The future of web animation is here, and it's driven by scroll!