Text reveal
Reveal a short piece of content with restrained motion.
textmotioncontent
Preview
Text reveal preview
Live · keyboard ready
Every word rises as it enters the viewport.
When to use
- Above-the-fold hero headlines that animate on page load.
- Landing page intros where text must appear on first paint even if scripts are slow.
When not to use
- Use in-view-title for section titles further down the page.
- Use scroll-highlight for a key paragraph that reveals with scroll.
- Use word-rotate when one word in the headline should cycle.
shadcn CLI
Also installs (1)
- manicat-foundation
Manual install(+)
registry.jsonjson
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "text-reveal",
"type": "registry:ui",
"title": "Text reveal",
"description": "Reveal a short piece of content with restrained motion.",
"categories": [
"text"
],
"dependencies": [],
"registryDependencies": [
"https://manicat.viraza.net/r/manicat-foundation.json"
],
"files": [
{
"path": "registry/components/text-reveal/text-reveal.tsx",
"type": "registry:component",
"target": "@components/manicat/text-reveal/text-reveal.tsx"
},
{
"path": "registry/components/text-reveal/text-reveal.module.css",
"type": "registry:component",
"target": "@components/manicat/text-reveal/text-reveal.module.css"
}
],
"docs": "Docs and live preview: https://uiarc.dev/components/text-reveal",
"meta": {
"tier": "free",
"kind": "component",
"docs": "https://manicat.viraza.net/components/text-reveal",
"markdown": "https://uiarc.dev/components/text-reveal/markdown",
"tags": [
"text",
"motion",
"content"
]
}
}Usage
Install the component, then copy this into your app. Change the content and the props to fit your screen.
example.tsxtsx
"use client";
import { TextReveal } from "@/components/manicat/text-reveal/text-reveal";
export function TextRevealExample() {
return (
<div className="w-full">
<TextReveal text="Every word rises as it enters the viewport." as="h2" />
</div>
);
}
Examples
Real screens rather than isolated props. Switch to Code to copy a whole example into your project.
Scroll-in headline Each word rises as the section enters the viewport.
Scroll-in headline
Each word rises as the section enters the viewport. preview
Live · keyboard ready
Every word rises as it enters the viewport.
scroll-in-headline-each-word-rises-as-the-section-enters-the-viewport-.tsxtsx
"use client";
import { TextReveal } from "@/components/manicat/text-reveal/text-reveal";
export function TextRevealHeadlineExample() {
return (
<div className="w-full">
<TextReveal text="Every word rises as it enters the viewport." as="h2" />
</div>
);
}
Accessibility
- The full text sits in a visually hidden span; the animated words are aria-hidden, so screen readers read one clean sentence.
- Line breaks are read as spaces.
- Pick the heading level with as so the page outline stays correct.
Motion
- Words rise out of a clip and sharpen from blur on a per-word stagger; total stagger is capped so long text never drags.
- The entrance is pure CSS, so text is never left hidden when scripts load slowly.
- Reduced motion drops the clip and rise and fades the words in quickly.
Responsive behavior
- The element caps at 24ch with balanced wrapping, so lines stay even on any width.
- Use \n only for breaks that work on every width, since forced breaks apply on mobile too.
Performance
- Pure CSS keyframes, no JavaScript animation or observers.
- Total stagger is capped, so long text does not lengthen the entrance; each word still gets its own blur filter.
Notes for AI
- Use for above-the-fold headlines that should animate on page load. For titles further down the page use in-view-title; for body copy worth slowing down on use scroll-highlight.
- It plays once per mount. Change the element's key to replay it.