Skip to main content

✨ Animating further

tip

With locomotive-scroll it's very easy to add a CSS progress to a specific DOM element. First let's start by adding some required HTML attributes to our block :

  • data-scroll => Enable viewport detection on an element.
  • data-scroll-speed => Specifies the parallax speed for the element. A negative value will reverse the direction of the parallax effect.
  • data-scroll-css-progress => Will add a CSS variable --progress to the element. This variable represents the current progress of the element and ranges between 0 and 1.

Now that we have LS all set-up, let's use it! We'll start easy with a simple parallax on our c-hero_image:

/views/partials/hero.twig
<div class="c-hero_image-wrapper">
<div class="c-hero_image">
<img
src="{{site.hero.img.src}}"
width="{{site.hero.img.width}}"
height="{{site.hero.img.height}}"
data-scroll {# Enables LS on this element #}
data-scroll-speed="-0.1" {# Add parallax #}
>
</div>
</div>
note

We're adding the parallax on the img tag to prevent a conflict between the CSS animation on .c-hero_image as both use the transform CSS property.

For the SWAG logo, we want to add a scaling effect relative to the scroll. For that we'll use the CSS progress feature

/views/partials/hero.twig
<figure 
class="c-hero"
aria-label="{{ site.hero.label }}"
data-scroll {# Enables LS on this element #}
data-scroll-css-progress {# This will add a `--progress` CSS variable to our element #}
>
<div class="c-hero_image-wrapper">
{# ... #}
</div>

<svg class="c-hero_logo" {# ... #}>
{# ... #}
</svg>
</figure>
tip

You can inspect the element and scroll to the --progress variable update in real time!

Now that we have this usefull data available in our CSS, let's put it to use:

assets/styles/components/_hero.scss
.c-hero_logo {
transform: translate3d(0,0,0) scaleY(calc(1 + var(--progress)));
transform-origin: center bottom;
}

And for even more life, let's add a staggered reveal effect on each character:

assets/styles/components/_hero.scss
.c-hero_logo {
// ...
overflow: visible;

@for $i from 1 through 4 {
html.is-ready & path:nth-child(#{$i}) {
animation: logoCharReveal 1s $easing #{0.1s * $i} both;
}
}
}

@keyframes logoCharReveal {
0% { opacity: 0; transform: translate3d(0,-50%,0); }
100% { opacity: 1; transform: translate3d(0,0%,0); }
}