Contrario

by Victor Matekole

Skip to content

clip-path and Scroll animations with vanilla CSS

Posted on:4 January 2024 at 01:20

Friends who run a design agency in Berlin tasked me with a rebuild of their 6yr old site. So, I took the opportunity to deep-dive into the latest developments of native CSS.

CSS has gotten really good — incorporating a lot of the functionalities that were once delegated to preprocessors and JS libraries. The site currently uses SASS(Bulma) and is built using Hugo. TailwindCSS has taken the place of Bulma, including some of the latest CSS features, some of which require polyfilling for cross-browser support:

I came across Scroll-animations via developedbyed which are currently supported in Chrome only. They allow you to do scroll-based animations that previously required JS event-listeners. Google released a wonderful set of devtools to help in development/debugging of scroll-animations. I recommend you take a look.

In the following animation the parent container of an image is cropped according to a clip-path rule. In this case it is a polygon — one of many shapes that can be defined as a mask. There is a brilliant tool (by Bennett Feely) that was used to define the path of the polygon-based mask. Here is a screencast of the resulting animation:

The animation masks the image with a parallelogram that progressively reduces (over 7 steps) to fully reveal the image:


@keyframes revealing {
    0% {
        clip-path: polygon(37% 0%, 100% 0%, 63% 100%, 0% 100%);
    }
    25% {
        clip-path: polygon(18% 0, 100% 0%, 83% 100%, 0% 100%);
    }
    50% {
        clip-path: polygon(14% 0, 100% 0%, 87% 100%, 0% 100%);
    }
    75% {
        clip-path: polygon(8% 0, 100% 0%, 92% 100%, 0% 100%);
    }
    85% {
        clip-path: polygon(4% 0, 100% 0%, 96% 100%, 0% 100%);
    }
    90% {
        clip-path: polygon(2% 0, 100% 0%, 98% 100%, 0% 100%);
    }
    95% {
        clip-path: polygon(1% 0, 100% 0%, 99% 100%, 0% 100%);
    }
    100% {
        clip-path: polygon(0, 0, 0 0, 0 0, 0 0);
    }
}
.grid-item {
    view-timeline-name: --grid-item;
    view-timeline-axis: block;

    animation: linear revealing both;
    animation-timeline: --grid-item;

    animation-range: entry 50% cover 50%;
}
<div class="grid-item">
	<img src="https://placehold.co/300x200/blue/white"/>
</div>

Line by line explanation for the scroll-animation code:

.grid-item {

    /** Targeted element to animate **/
    view-timeline-name: --grid-item;
    /** Timeline is along block axis(default value) **/
    view-timeline-axis: block;

    /** Defines animation to be used and the function of time the animation will be rendered  */
    animation: linear revealing both;
    /** Animation timeline to use for the animation **/
    animation-timeline: --grid-item;
		/** Begin to animate when subject is 50% in view and ends when the last part of the element is fully in view **/
    animation-range: entry 50% cover 50%;
}

The same rendered in a codepen(only works in Chrome):

See the Pen Clip Path demonstration by VMPEN (@vmpen) on CodePen.