
Staggered Word Reveal
FreeCreate elegant word-by-word text animations for your projects.
Free · Opens the source repo
What Staggered Word Reveal does
Staggered Word Reveal is a JavaScript-based skill designed to enhance the presentation of short text elements through a subtle word-by-word reveal animation. This skill is particularly useful for web developers and designers looking to create premium effects for headlines, section intros, or marketing text. The animation is triggered when the text enters the viewport, ensuring that it captures the user’s attention without overwhelming them. The default motion settings provide a calm and cinematic feel, making it suitable for high-quality portfolio displays and other editorial-style content.
The implementation is straightforward, utilizing the IntersectionObserver API to detect when the text is visible on the screen. Each word fades in and rises slightly from below, creating a dynamic yet restrained effect. The skill is built to be accessible; it ensures that the original text is still readable by screen readers and maintains visibility even when JavaScript is disabled. This focus on accessibility and user experience makes it a valuable addition for any project that prioritizes both aesthetics and functionality.
Developers can easily integrate this skill into their existing projects by following the provided HTML and CSS guidelines. The JavaScript code handles the splitting of the text into individual words, applying the necessary classes for the animation. Additionally, it includes provisions for users who prefer reduced motion, ensuring that the text remains legible without animations. This makes Staggered Word Reveal a versatile tool for enhancing user interfaces while adhering to best practices in web development.
When to use it
Use this skill when you want to add a sophisticated word reveal effect to short text elements that should capture attention as they enter the viewport.
When not to use it
Avoid using it for long paragraphs or when text contains links or buttons, as it is designed for short, impactful phrases only.
What you can build with it
Portfolio Showcase
Use Staggered Word Reveal to enhance your portfolio's landing page with elegant text animations that draw attention to key headlines.
Marketing Campaigns
Integrate this skill into marketing landing pages to create impactful reveals for promotional text that engages visitors.
Editorial Websites
Implement the skill on editorial sites to provide a premium feel to quotes and section introductions, enhancing the reading experience.
How to install Staggered Word Reveal
View source1. Install with the skills CLI
npx skills add mengto/skills/staggered-word-reveal --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by mengtoStaggered 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.
Frequently asked questions about Staggered Word Reveal
Similar skills
Penpot UI/UX Design
Create professional UI/UX designs in Penpot with ease.
UX Theming
Streamline your VS Code theming process with best practices.
Wireframe
Create low-fidelity UI wireframes in SVG format.
Waitlist Page
Create a clean, focused pre-launch landing page.
Hallmark
Design skill for creating unique, structured UIs.
UI Styling
Create beautiful, accessible user interfaces effortlessly.
