Trigger CSS Animations On Scroll – Add CSS Transition using Intersection Observer API

You might be thinking it’s difficult to do fancy CSS animation with a mouse scroll. But infarct it’s fundamentally much simpler. You just need to tell the browser when to start the animation. Which could be triggered by simple javascript.

If you manage to add a class to your scrolling element, you can actually animate that element or any child element inside that element. So the magic trick here is to add a class dynamically on the scroll. This can be done by listening to window scroll events. There is so much you can do with this simple method. Here I have listed my personal favorite methods and libraries to do fancy scroll animations.

Trigger Animations On Scroll Without using the library:

The idea here is to create scrollable sections. This will act as the container of the main element. So We’ll create some sections and give them a class name so JavaScript can observe those parent sections. This is going to be the base of the HTML structure. It would look something like the one below.

<div class="scroll__container">
<section>
<h2>Section 1</h2>
</section>
<section>
<h2>Section 2</h2>
</section>
<section>
<h2>Section 3</h2>
</section>
<section>
<h2>Section 4</h2>
</section>
</div>

Add CSS

We’ll just disable the body scroll and enable scroll within .scroll_container because we want to take advantage of snapping while scrolling sections.

This is the simplest version of code that will require understanding the demo. We have the parent element and child elements which will have an active class on the scroll. This method of adding a class will enable to triggering of CSS animations on scroll.

Just for the sake of simplicity, we’ll make the height of the container 100% height so we can enjoy the show, It can, however, be any height depending upon the design. We’ll use a Simple CSS class that would look something like this.

body {
overflow: hidden;
perspective: 1000px;
font-weight:800;
overflow-x: hidden;
}
.scroll__container {
height: 100vh;
overflow-y: scroll;
scroll-snap-type: y mandatory;
}
section {
height: 100vh;
scroll-snap-align: center;
}

Add Javascript

Can I trigger CSS animations on scroll without Javascript?

The short answer is NO. Window scrolling is an event and CSS itself is not capable of detecting event changes as of now. So we must use javascript to measure the scroll and trigger something to which CSS can react. We do it using adding a new class to the section. There are experimental features of Chrome that let you do control CSS animation on scroll without javascript. But it’s just in experimenting mode right now.

There are two popular and easy ways we can detect scrolling and add class to the section.

1. Add Javascript: Using OffsetTop

var sections = document.querySelectorAll('section');
var container = document.querySelector('.scroll__container');
container.addEventListener('scroll', function () {
sections.forEach((e, i) => {
var top = (e.getBoundingClientRect().top);
if (top == 0) {
e.classList.add('is-inview')
} else {
e.classList.remove('is-inview')
}
});
})
container.dispatchEvent(newCustomEvent('scroll'));

This script just adds a class to the section which is currently in view. This script is not fail-safe because it heavily relies on scroll-snap-type: y mandatory and will work for scrolling top to bottom. This code uses snap scrolling and Offset of the scrolling to detect which element is scrolled all the way to its height. Check-out the demo below to see this script in action. [ GITHUB ]

This demo uses simple js to add class and some CSS transitions. More complex animations can be done using the same add class method. For more control over scrolling sections, there is a better way to detect viewport intersection. Which is explained in the next method.

2. Add Javascript: Intersection Observer

This will give you a usable structure to test. Now comes the meat. The observer javascript:

var sections = document.querySelectorAll('section');
var options = {
rootMargin: '0px',
threshold: 0.25
}
var callback = (entries) => {
entries.forEach((entry) => {
var target = entry.target;
if (entry.intersectionRatio >= 0.25) {
target.classList.add("is-inview");
} else {
target.classList.remove("is-inview");
}
})
}
var observer = new IntersectionObserver(callback, options)
sections.forEach((section, index) => {
observer.observe(section)
})

This will enable you to quickly add some page scroll effects. If this is something you’re looking for, then this should be it. No libraries and no overhead scripts.

But if you want to go a little complex with your implementation, You should consider using professional libraries, which will give you more control and compatibility overa few lines of code. I personally like to use libraries because I like controlled scroll animation with my animations.

How animation is triggered on scroll

In the example, we have implemented the IntersectionObserver API method. Now viewport can register a callback function to observe which element enters or leaves the viewport. This could be extremely useful to lazy load big content because content can be loaded only when needed. But we’re just using it for adding /removing classes so we can animate our dom elements.

We can configure callbacks with Intersection Observer API when a target element intersects the parent element.

Intersection observer options:

  • Root: ancestor of the target element(s)
  • rootMargin: margin for the parent element
  • Threshold: value / values of scroll percentage [0 -1]

You can get more understanding of what happens to observed elements when scrolling the window:

This works not only within the frame but try to scroll your browser window and see what happens.

The Threshold value in the above example is set to 0.6, so any element entering the viewport will be observed by the javascript and the class can be added using the “isIntersecting” value. Similarly, the class can be removed by a small javascript. The demo shows how sections behave when any class is added or removed to themselves when they are in the viewport window.

With this little configuration, you can animate objects in HML. In my example, I have only used CSS Transitions, but we can use @keyframes to animate a variety of animations. There are debts on whether to use transitions or animations, But I use transitions most of the time. I combine them with JavaScript for control sequence and performance. I have a detailed explanation of how CSS animations work if @keyframes is the way you want to go.

Triggering CSS Transitions On Scroll:

When any class is applied to the parent, we can use different CSS rules on child objects to make a transition. for example: when we have a section with no class, we’ll have heading opacity set to 0. so the heading H2 will be hidden. When we add class .is-inview to the section, we. can add another rule section.is-inview h2 and have opacity of 1. We’ll use the transition attribute to notify the browser to smoothly transit the property.  in this case, heading H2 will have opacity animation when class .is-invew is applied to its parent section.

section h2{
opacity:0; transition:opacity 500ms;
}
section.is-inview h2{
opacity:1;
}

What else can we do with it?

Trigger CSS Animation on Scroll:

We can rigger animation sequences when the class is applied. Let’s say, we have a dummy animation say smoke, and we want it to appear when a section is in view, we can use the same technique to start the animation. with animation-delay, we can have staging animations.

@keyframes smoke {
0% {
opacity: 0;
background-size: 100%;
}
35% {
opacity: 0.7;
}
90% {
opacity: 0.7;
}
100% {
opacity: 0;
background-size: 110%;
}
}
section.is-inview span{
animation: smoke 15s infinite;
}

Personally, I like to start from scratch and I always keep things at a minimum. With this small script, I can create as many transitions as I want and trigger animations on scroll. But in production and when I have time constraints, I use libraries to kickstart my page design process.

So here is my top 10 list of scroll libraries you can use in your next project… 

No, I am kidding.

You don’t actually need 10 libraries to get the job done. You can actually need the best suited for your purposes. I mostly use one of these two libraries. They do the trick for me mostly. Here is a short example of what I was able to do with just this little script.

I like to mention some of the libraries though,

AOS : (Animate on Scroll)

For a simple scroll animation bundle, AOS is a great option. You just need to define certain attributes in your code and the library will take care of the rest. AOS works on the same principle defined above, It adds class to the element when we scroll the page. But It is packed with many premade CSS animations that you can trigger on the scroll. The main features of this library are it’s

  • It’s animations
  • Add delays
  • Add repetition
  • Trigger Custom Animation
  • Change directions
  • Configure offsets
  • Easing support

The magical function AOS uses to add a class on the section is

AOS.init();

We’re not using Its data-aos animations to do animations from the book. But we’re just using its added class aos-animate to trigger our animations.

ScrollMagic

This library gives even further control over our scroll event. You can go creative with your scroll movement using ScrollMagic. Sure it has a learning curve but it’s better to learn one library that works for all your interactions and micro-interactions.

The benefits of using this library are:

  • Animation based on scroll position
  • Trigger animation by adding class
  • Enable synchronized animation on the scroll
  • Pinning element
  • Parallax
  • Easing libraries support
  • Callbacks and many more…

We’re not going to explore all the features on scrollMagic. But We’ll just use the AddClass method and see how creative we could go with it. We can use a simple piece of code to do exactly the same thing vanilla js does.

<script>
var controller = new ScrollMagic.Controller({globalSceneOptions: {duration: '100%'}});
document.querySelectorAll('section').forEach(function(e){
new ScrollMagic.Scene({triggerElement: e})
.setClassToggle(e,"is-inview")
.addIndicators()
.addTo(controller);
})
</script>

Note this library gives us the ability to add debug indicators. Super helpful while developing specific interactions. This gives you better control of our animated elements.

Should You Use Libraries to Trigger CSS Animations on Scroll?

If registering for the simple event will give you the ability to animate your elements using CSS, then you should definitely give it a try. But If you’re a newbie then experimenting from scratch may affect your productivity. You can search the internet for lots of inspiration and samples to kickstart your cool webpage. But Adding a class is the easiest way to trigger CSS animation on scroll.

Continue Reading

rhodium

Rhodium Developers

Framework: WordPress – Elementor
Requirement: New custom-made website with SEO optimization
shangri_la
development

Problem

It’s a start-up company and it did not have enough stuff to showcase its work. It faced the challenge of establishing a strong online presence to attract potential clients. They wanted a visually appealing website that would convey their professionalism and expertise.

Our Plan

Execution

1A premium website template was designed in Figma. Blueprints of the home page and other internal pages were created. The color palette has been chosen wisely to exude elegance without compromising usability – sleek beige typography against crisp black backgrounds creates an impactful visual contrast that enhances readability and attention. 

2By using strong visuals such as high-quality images and graphics showcasing their past projects, we aimed to convey their expertise and build trust with potential clients. The overall tone we maintained throughout the design process was professional yet approachable, reflecting the client’s brand image as a reliable and innovative construction company.

3 By incorporating intuitive navigation features and user-friendly interfaces, we ensured seamless browsing experiences for potential clients. By focusing on creating internal pages that offered valuable content and intuitive navigation, we were able to provide users with an immersive and informative experience. With intuitive menu options, easy-to-use contact forms, and visually appealing project showcases, visitors are certain to find exactly what they need with minimal effort.

4 One of the primary goals for this project was to showcase the exceptional quality of their work through an impressive gallery section. By leveraging the power of visually appealing images and intuitive navigation, we successfully transformed their website into a virtual gallery that entices visitors to explore more.

5 A major challenge encountered during the project was effectively showcasing Rodium’s unique approach to building construction. By incorporating captivating visuals and interactive elements, such as 2D models and virtual tours, the website successfully demonstrates the intricate processes involved in constructing high-quality buildings. Additionally, clear and concise descriptions were implemented to explain each step of the construction journey, making it easily understandable for potential clients who may not be familiar with technical jargon.

Final Testing

During the testing phase, every aspect of the website will be put under a microscope to ensure its seamless functionality and performance. From checking cross-browser compatibility to ensuring smooth navigation on different devices and screen sizes, no stone will be left unturned. The comprehensive testing process aims not only to identify any potential glitches or bugs but also to guarantee that the user experience is intuitive and flawless.

By utilizing the latest techniques in search engine optimization algorithms, this website is now primed to attract organic traffic and boost its online presence.