How do I create a CSS-only scroll triggered animation?

Creating a CSS-only Scroll Triggered Animation

In this blog post, we will explore how to create a CSS-only scroll triggered animation. This means that the animation will start or play when the user scrolls the page, without the need for any JavaScript. We will accomplish this using CSS keyframes, transitions, and the @supports rule to ensure a graceful fallback for browsers that do not support these features.

Getting Started:

To create a CSS-only scroll triggered animation, we will use a combination of CSS properties and techniques, such as:

  1. position: sticky;
  2. @keyframes
  3. animation
  4. @supports (Optional, for graceful degradation)

Let’s start by creating a basic HTML structure to hold our content and the element we want to animate.

<!-- HTML -->
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="content">
    <h1>Scroll Triggered Animation</h1>
    <p>Keep scrolling to see the animation...</p>
    <div class="scroll-area">
      <div class="animated-element">I'm animated!</div>
    </div>
  </div>
</body>
</html>

Now, let’s create a CSS file (styles.css) and style our elements.

/* CSS */
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
}

.content {
max-width: 800px;
margin: 0 auto;
padding: 1rem;
}

.scroll-area {
height: 200vh; /* This will create a scrolling area */
}

.animated-element {
width: 200px;
padding: 20px;
background-color: coral;
color: white;
text-align: center;
border-radius: 4px;
}

Creating the Animation:

We will use the @keyframes rule to define our animation. Let’s create a simple fade-in animation.

/* CSS */
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

Now, let’s apply this animation to our .animated-element and use the position: sticky; property to trigger the animation when the element reaches a specific position in the viewport.

/* CSS /
.animated-element {
/ ...previous styles... */

position: sticky;
top: 50%; /* The animation will trigger when the element is 50% from the top of the viewport */
animation-name: fadeIn;
animation-duration: 1s;
animation-fill-mode: both;
animation-play-state: paused;
}

We’ll also need to apply the animation only when the element is stuck to the top of the viewport. We can use the :is() pseudo-class and the :target pseudo-class to achieve this.

/* CSS */
.animated-element:is(:target) {
animation-play-state: running;
}

Graceful Degradation (Optional):

To provide a graceful fallback for browsers that don’t support position: sticky;, we can use the @supports rule.

/* CSS /
@supports (position: sticky) or (-webkit-sticky: sticky) {
.animated-element {
/ ...sticky styles and animation... */
}

.animated-element:is(:target) {
/* ...animation play state... */
}
}

With the styles above, if a browser doesn’t support the position: sticky;, the animation will not be applied, and the content will be displayed without any issues.

Here’s the complete CSS code for reference:

/* CSS */
body {
  font-family: Arial, sans-serif;
  line-height: 1.6;
  margin: 0;
  padding: 0;
}

.content {
  max-width: 800px;
  margin: 0 auto;
  padding: 1rem;
}

.scroll-area {
  height: 200vh; /* This will create a scrolling area */
}

.animated-element {
  width: 200px;
  padding: 20px;
  background-color: coral;
  color: white;
  text-align: center;
  border-radius: 4px;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

@supports (position: sticky) or (-webkit-sticky: sticky) {
  .animated-element {
    position: sticky;
    top: 50%; /* The animation will trigger when the element is 50% from the top of the viewport */
    animation-name: fadeIn;
    animation-duration: 1s;
    animation-fill-mode: both;
    animation-play-state: paused;
  }

  .animated-element:is(:target) {
    animation-play-state: running;
  }
}

Using these techniques, you can create a wide range of scroll triggered animations to enhance the user experience on your website. Remember, it’s important to use these animations judiciously and not to overdo them, as too many animations can distract and annoy the user.

Conclusion:

In this blog post, we have learned how to create a CSS-only scroll triggered animation without any JavaScript. We used the position: sticky; property in combination with CSS keyframes and animations to achieve this effect. Furthermore, we provided a graceful fallback for browsers that do not support the position: sticky; property using the @supports rule.

Got question?

Submit it here

© All rights reserved.