Staggered Word Reveal
Meng ToCommunityCreated by Meng To
- Skill
- Tool integration
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a robust implementation for creating staggered, editorial-style text reveal animations. By splitting text into individual word spans and using the IntersectionObserver API, it ensures that headlines and short copy fade and rise into view gracefully as the user scrolls. The implementation prioritizes accessibility and performance by maintaining original text for screen readers, ensuring content remains visible if JavaScript fails, and respecting user reduced-motion preferences.
What it does
- Splits text content into individual word spans while preserving original accessibility labels.
- Triggers a staggered fade-in and slide-up animation using CSS transitions.
- Uses IntersectionObserver to trigger animations only when elements enter the viewport.
- Ensures content is readable and visible even if JavaScript is disabled.
- Includes built-in support for user-defined reduced-motion preferences.
- Provides guidance for integrating the animation logic into modern frameworks like React or Vue.
When to use it
- When you need a premium, restrained animation for hero headlines or section intros.
- When you want to avoid heavy animation libraries for simple text reveal effects.
- When you need to ensure animations are accessible and performant.
- When you want to trigger an animation exactly once upon initial scroll into view.
Advantages
- Lightweight implementation without external dependencies.
- Maintains semantic integrity for screen readers.
- Graceful degradation for non-JS environments.
- Respects system-level reduced-motion settings.
- Cinematic, editorial aesthetic suitable for high-end portfolios.
Usage examples
- “How do I add a staggered word reveal to my hero headline?”
- Apply the data-word-reveal attribute to your h1 tag and include the provided CSS and JS snippets to enable the scroll-triggered animation.
- “Can I use this with Framer Motion?”
- Yes, the skill provides specific motion tokens and timing parameters to replicate the effect using Framer Motion's animation properties.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/mengto/staggered-word-reveal/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip staggered-word-reveal.zip -d .agents/skills
Documentation by Meng To
Staggered Word Reveal
Use When
A short headline, intro, or pull quote should reveal word by word.
The motion should feel editorial, premium, and restrained.
The reveal should trigger only once when the text enters the viewport.
The project does not need heavy GSAP SplitText behavior.
Motion Defaults
Initial state:
opacity: 0,transform: translateY(20px).Final state:
opacity: 1,transform: translateY(0).Duration:
0.8s.Ease:
cubic-bezier(0.16, 1, 0.3, 1).Stagger:
0.06sto0.08sper word. Default to0.07s.Trigger: start around
20%visible, with a slight lower viewport bias.Replay: once only.
HTML
<h1 class="word-reveal" data-word-reveal>
Build interfaces that feel calm, cinematic, and alive.
</h1>CSS
Keep no-JS content visible. Hide only after JavaScript is active and before the text has been split.
.word-reveal {
visibility: visible;
}
html.js .word-reveal[data-word-reveal]:not(.is-ready) {
opacity: 0;
}
.word-reveal__word {
display: inline-block;
opacity: 0;
transform: translate3d(0, 20px, 0);
transition:
opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1),
transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);
transition-delay: calc(var(--word-index) * 0.07s);
will-change: opacity, transform;
}
.word-reveal.is-visible .word-reveal__word {
opacity: 1;
transform: translate3d(0, 0, 0);
}
@media (prefers-reduced-motion: reduce) {
html.js .word-reveal[data-word-reveal]:not(.is-ready),
.word-reveal__word {
opacity: 1;
transform: none;
transition: none;
}
}JavaScript
This splitter preserves spaces, avoids innerHTML, exposes the original sentence to screen readers, and unobserves after the first reveal.
document.documentElement.classList.add("js");
function splitWordReveal(element) {
if (element.dataset.wordRevealReady === "true") return;
const text = element.textContent || "";
const parts = text.split(/(\s+)/);
let wordIndex = 0;
element.textContent = "";
element.setAttribute("aria-label", text.trim());
parts.forEach((part) => {
if (!part.trim()) {
element.appendChild(document.createTextNode(part));
return;
}
const word = document.createElement("span");
word.className = "word-reveal__word";
word.setAttribute("aria-hidden", "true");
word.style.setProperty("--word-index", wordIndex);
word.textContent = part;
element.appendChild(word);
wordIndex += 1;
});
element.dataset.wordRevealReady = "true";
element.classList.add("is-ready");
}
function initWordReveals(selector = "[data-word-reveal]") {
const elements = Array.from(document.querySelectorAll(selector));
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (reduceMotion || !("IntersectionObserver" in window)) {
elements.forEach((element) => {
element.classList.add("is-ready", "is-visible");
});
return;
}
const observer = new IntersectionObserver(
(entries, io) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
entry.target.classList.add("is-visible");
io.unobserve(entry.target);
});
},
{
threshold: 0.2,
rootMargin: "0px 0px -10% 0px",
}
);
elements.forEach((element) => {
splitWordReveal(element);
observer.observe(element);
});
}
document.addEventListener("DOMContentLoaded", () => {
initWordReveals();
});Framework Notes
React/Vue/Svelte: run the splitter after mount, then clean up observer instances on route changes.
Framer Motion: keep the same tokens:
y: 20,opacity: 0, duration0.8, ease[0.16, 1, 0.3, 1], stagger0.06to0.08,once: true.GSAP: use
fromTo(words, { y: 20, opacity: 0 }, { y: 0, opacity: 1, duration: 0.8, ease: "expo.out", stagger: 0.07 }).
Taste Rules
Use on short text: headlines, subheads, labels, and quotes. Avoid long paragraphs.
Stagger words, not letters, for a calmer premium feel.
Keep the offset subtle. Do not add bounce, rotation, or large blur.
Animate
transformandopacityonly.Do not split text containing links, buttons, or meaningful inline markup.
If wrapping is important, initialize after web fonts are ready.
Quick Checks
Text is visible when JavaScript is disabled.
Words begin at
translateY(20px)andopacity: 0.Each word reveals once with a
0.06sto0.08sdelay.Repeated scrolling does not replay the animation.
Reduced-motion users see static readable text.
Files
- ATTRIBUTION.mdAdded by AutoGineer864 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md4.8 KiB
- demo/PROMPT.md2.0 KiB
- demo/index.html16.1 KiB
- demo/preview.jpg69.7 KiB
demo/PROMPT.md
Staggered Word Reveal Demo Prompts
Minimal prompt
Use $staggered-word-reveal to create a polished standalone HTML example that clearly demonstrates the skill.
Recreate the demo
Use $staggered-word-reveal to build a responsive reference demo for this capability:
Create subtle editorial word-by-word text reveal animations where each word fades and rises into place once it enters the viewport. Use for premium portfolio headlines, hero copy, section intros, and short marketing text that needs a cinematic staggered reveal with IntersectionObserver or in-view detection.
Direction
Make choreography, easing, and replay behavior the primary demonstration.
Use an art-directed composition with one clear focal point, restrained supporting copy, and enough surrounding interface to show how the technique behaves in a real product or landing page.
Canonical example
Reveal the lines Motion should, explain the, and next state in sequence.
Use a four-part timeline and a keyboard-accessible Replay sequence control.
Deliverable
Create demo/index.html as a standalone document.
Keep CSS and JavaScript inline.
Put any required images, fonts, models, textures, or vendor files in demo/assets/.
Do not add a framework, package manager, build step, or node_modules.
Add controls only when they help inspect or replay the technique.
Acceptance checks
Keep the demo responsive from 390px through 1440px.
Use semantic HTML, visible focus states, and reduced-motion handling.
Keep all HTML, CSS, and JavaScript inside demo/index.html.
Use only relative local asset paths.
Provide a replay control and stop continuous work when the animation settles.
Remove nonessential movement under prefers-reduced-motion.
Remix prompt
Use $staggered-word-reveal and keep the same implementation contract, but change the subject, copy, palette, and content hierarchy. Preserve the core technique, accessibility behavior, responsive rules, and performance constraints demonstrated by the reference.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Meng To
- Publisher
- Meng To (Community)
- Source
- MengTo/Skills · agent-skills/web-design/staggered-word-reveal · commit 5ea1661
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Meng To.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download staggered-word-reveal.zip