
Documentation
Webflow
Code
Setup: External Scripts
External Scripts in Webflow
Make sure to always put the External Scripts before the Javascript step of the resource.
In this video you learn where to put these in your Webflow project? Or how to include a paid GSAP Club plugin in your project?
HTML
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lottie-web@5.12.2/build/player/lottie.min.js"></script>
Step 1: Copy structure to Webflow
Copy structure to Webflow
In the video below we described how you can copy + paste the structure of this resource to your Webflow project.
Copy to Webflow
Webflow structure is not required for this resource.
Step 1: Add HTML
HTML
<div class="lottie-demo-card">
<span class="lottie-demo-card__tag">Animation #001</span>
<div data-lottie-frame="10" data-lottie data-lottie-src="https://osmo.b-cdn.net/resource-media/lottie-demo-piggy-1750244874581.json" class="lottie-demo-card__animation"></div>
<h2 class="lottie-demo-card__heading">Save money</h2>
</div>
HTML structure is not required for this resource.
Step 2: Add CSS
CSS
.lottie-demo-card {
aspect-ratio: 1 / 1.25;
background-color: #fff;
border-radius: 1.5rem;
flex-flow: column;
justify-content: flex-end;
align-items: flex-start;
width: 26.5rem;
padding: 2rem;
display: flex;
position: relative;
}
.lottie-demo-card__heading {
margin: 0;
font-size: 2rem;
font-weight: 500;
line-height: 1.2;
}
.lottie-demo-card__animation {
z-index: 1;
position: absolute;
top: 2rem;
left: 2rem;
right: 2rem;
}
.lottie-demo-card__tag {
z-index: 2;
background-color: #f7e8d3;
border-radius: 100em;
padding: .5em .75em;
font-size: .875rem;
line-height: 1;
position: absolute;
top: 2rem;
left: 2rem;
}
Step 2: Add custom Javascript
Custom Javascript in Webflow
In this video, Ilja gives you some guidance about using JavaScript in Webflow:
Step 2: Add Javascript
Step 3: Add Javascript
Javascript
gsap.registerPlugin(ScrollTrigger);
function initLottieAnimations() {
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
document.querySelectorAll("[data-lottie]").forEach(target => {
let anim; // Store animation reference
ScrollTrigger.create({
trigger: target,
start: "top bottom+=50%", // Load lottie once it's half a viewport away from entering
end: "bottom top-=25%",
onEnter: handleEnter,
onEnterBack: handleEnter,
onLeave: handleLeave,
onLeaveBack: handleLeave,
});
function handleEnter() {
// Handle first enter: create a lottie player
if (!target.hasAttribute("data-lottie-fired")) {
target.setAttribute("data-lottie-fired", "true");
anim = lottie.loadAnimation({
container: target,
renderer: "svg",
loop: true,
autoplay: !reduceMotion,
path: target.getAttribute("data-lottie-src"),
});
// If reduced motion is ON, load the first frame as a static SVG image
// Add [data-lottie-frame] with the number of your desired frame if not 0
anim.addEventListener("DOMLoaded", () => {
if (reduceMotion) {
const frame = parseInt(target.getAttribute("data-lottie-frame") || "0", 10);
anim.goToAndStop(frame, true);
}
});
} else if (anim && !reduceMotion) {
// If lottie enters view again, and is already created, simply play it
anim.play();
}
}
function handleLeave() {
if (anim && !reduceMotion) {
anim.pause();
}
}
});
}
document.addEventListener("DOMContentLoaded", () =>{
initLottieAnimations();
});
Step 3: Add custom CSS
Step 2: Add custom CSS
Custom CSS in Webflow
Curious about where to put custom CSS in Webflow? Ilja explains it in the below video:
CSS
Documentation
This script automatically initializes Lottie animations on any element with data-lottie
and a data-lottie-src
. The function makes sure that a Lottie is only initialised when a user is about to see them. Reducing initial payload, and improving your page speed. After all, if you have a Lottie in the footer of your website, there's no need to load it immediately.
Accessibility
Since Lotties can be pretty crazy and/or overwhelming and distracting, we have a built-in checker for when a user prefers 'reduced motion'. If this is the case, the function will load only the first frame of your Lottie, making it look like a static SVG!
Attributes
data-lottie
— required
Marks an element as a Lottie target. This can just be an empty div
with a width to it. Height will be set by the Lottie file.
data-lottie-src
— required
URL or path to the .json animation file. Add this to the same element that you gave the data-lottie
attribute to. If you're curious where we host our files, checkout this YouTube video from Ilja.
data-lottie-frame
— optional
Frame number to display when reduced-motion is active (defaults to 0).
Performance
As an extra benefit, the function will pause an animation once it leaves the viewport. This reduces strain on your CPU/GPU to keep animating all those complex SVG animations when nobody is seeing them anyway. Once the Lottie is scrolled back into view, we simply start playing them again.
These awesome Lotties in our demo were sourced from Vladislav Sholohov
Resource Details
Last updated
June 18, 2025
Type
The Vault
Category
Utilities & Scripts
Need help?
Join Slack