Use when you need scroll-driven motion that feels intentional instead of noisy or overdone.
Real-world examples
Live HTML demos for this skill — rendered directly in the page. 3 examples.
- 01
Staggered feature cards
IntersectionObserver pauses CSS animations until each card enters view, then plays a blur-fade with staggered delays.
- 02
Editorial scroll sequence
Long-form article blocks reveal once as they cross the viewport — headings, body, and pull quotes timed with rootMargin.
- 03
Split media showcase
Alternating image/copy rows slide in from opposite sides using the same animate-on-scroll observer pattern.
Skill markdown
# Animation On Scroll Skill
## Workflow
1. Confirm animation style, timing, and whether animations should run once or repeat.
2. Provide the keyframes + JS observer snippet and the exact Tailwind class to apply.
3. Offer focused tweaks only (threshold, rootMargin, duration, delay, transform/blur values).
## Usage checklist
- Insert the JS snippet in the `<head>` after the keyframes.
- Add the animation class and `animate-on-scroll` to elements.
- Ensure your keyframes name matches the Tailwind animation reference.
## IntersectionObserver trigger
```html
<script>
/*
Sequence animation on scroll when visible. Requires Animation Keyframe. Usage:
1) Insert this code in the <head> along with the Animation Keyframe code.
2) Add to Tailwind Classes: [animation:animationIn_0.8s_ease-out_0.1s_both] animate-on-scroll
*/
(function () {
// Inject CSS for paused/running states
const style = document.createElement("style");
style.textContent = `
/* Default: paused */
.animate-on-scroll { animation-play-state: paused !important; }
/* Activated by JS */
.animate-on-scroll.animate { animation-play-state: running !important; }
`;
document.head.appendChild(style);
const once = true;
if (!window.__inViewIO) {
window.__inViewIO = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add("animate");
if (once) window.__inViewIO.unobserve(entry.target);
}
});
}, { threshold: 0.2, rootMargin: "0px 0px -10% 0px" });
}
window.initInViewAnimations = function (selector = ".animate-on-scroll") {
document.querySelectorAll(selector).forEach((el) => {
window.__inViewIO.observe(el); // observing twice is a no-op
});
};
document.addEventListener("DOMContentLoaded", () => initInViewAnimations());
})();
</script>
```
## Keyframes
```html
<style>
/*
Sequence animation intro. Usage:
1) Insert this code in the <head>
2) Add to Tailwind Classes: [animation:animationIn_0.8s_ease-out_0.1s_both]
*/
@keyframes animationIn {
0% {
opacity: 0;
transform: translateY(30px);
filter: blur(8px);
}
100% {
opacity: 1;
transform: translateY(0);
filter: blur(0px);
}
}
</style>
```
## Tailwind example
```html
<div class="animate-on-scroll [animation:animationIn_0.8s_ease-out_0.1s_both]">
...
</div>
```
## Customization knobs
- Trigger: adjust `threshold` and `rootMargin` for earlier/later reveals.
- Repeat: set `once = false` to allow replays when re-entering.
- Motion: tweak `translateY` and `blur` in keyframes.
- Timing: change duration and delay in the Tailwind animation value.
## Common pitfalls
- Forgetting to include the keyframes before the JS snippet.
- Using a different keyframe name than in the Tailwind animation.
- Animations not running because the element is already in view before observer init.
## Questions to ask when specs are missing
- Should animations run once or every time the element re-enters?
- How far before entering the viewport should they start?
- What motion style (fade, slide, blur, scale) do you want?More from MengTo
- Animation SystemsUse when building a coherent animation system instead of one-off motion tweaks.
- Beautiful ShadowsUse when a UI needs better depth, elevation, and shadow treatment without looking muddy.
- CobejsUse when building lightweight animated globe or orb visuals with Cobe.
- Company LogosUse when laying out logos, trust rows, or brand collections in a clean and balanced way.
- Container LinesUse when using borders and container structure as part of the visual system.
- Design First UI PromptingUse when you want to turn a product goal into a design-first UI prompt with clear layout, type, color, and constraint choices.