Animation
Using Intersection Observer and Tailwind for a "fade-in and up" animation.
<script>
const fadeinupList = document.querySelectorAll(".fadeinup")
const callback = (entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.remove("translate-y-6", "opacity-0", "sm:translate-y-4", "sm:opacity-0")
}
});
};
const options = {
root: null,
rootMargin: '-100px',
threshold: 0
}
const observer = new IntersectionObserver(callback, options)
fadeinupList.forEach(item => {
observer.observe(item)
})
</script>
Installation
Add the above js at the bottom of the page.
Add the
fadeinup
class to any element that will be animated.The animated element needs the transition settings for the initial state.
Classes to add for basic example:
transition transform translate-y-6 opacity-0 fadeinup
Responsive example, with delay:
transition transform sm:delay-300 sm:translate-y-4 sm:opacity-0 fadeinup
In the above example the delay is only applied on breakpoints sm
and up. This is useful when we want a slight delay on additional columns, but on mobile there is no delay.
In this example, the fade-in and translate-up are also only applied on breakpoints sm
and up.
Be sure that all the classes are set to be removed to affect the animation.
entry.target.classList.remove("translate-y-4", "opacity-0", "sm:translate-y-4", "sm:opacity-0")
Options
rootMargin: '-100px'
means the element will need to be scrolled 100px into the viewport before it is triggered.
threshold of 0 means as soon as any part of the element is visible it will be triggered. A value of 1 means the entire element must be visible to be triggered. Or it can be any fraction e.g. 0.5
Based on the Introduction to scroll animations with Intersection Observer tutorial.
Stagger Animation
Tailwind CSS to add for a three column staggered animation from md
breakpoint. With a three column layout this will add a 250ms delay to the items in the second column and a 500ms delay to the items in the third column.
<div class="grid md:grid-cols-12 md:[&>*:nth-child(3n+2)]:delay-150 md:[&>*:nth-child(3n)]:delay-300">
<div class="md:col-span-4">Col 1</div>
<div class="md:col-span-4">Col 2</div>
<div class="md:col-span-4">Col 3</div>
</div>
Here is an example where it goes from one column, to three column and then finally to four column. Target a breakpoint range by stacking a responsive modifier like md
with the max-*
modifier for the next breakpoint.
<div class="grid md:grid-cols-12
md:max-xl:[&>*:nth-child(3n+2)]:delay-150
md:max-xl:[&>*:nth-child(3n)]:delay-300
xl:[&>*:nth-child(4n+2)]:delay-150
xl:[&>*:nth-child(4n+3)]:delay-300
xl:[&>*:nth-child(4n)]:delay-[450ms]
">
<div class="md:col-span-4 xl:col-span-3">Col 1</div>
<div class="md:col-span-4 xl:col-span-3">Col 2</div>
<div class="md:col-span-4 xl:col-span-3">Col 3</div>
<div class="md:col-span-4 xl:col-span-3">Col 1 (md) or Col 4 (xl)</div>
</div>
Links
How to Detect When a Sticky Element Gets Pinned
https://css-tricks.com/an-explanation-of-how-the-intersection-observer-watches/
https://www.smashingmagazine.com/2021/07/dynamic-header-intersection-observer/