Text that animates in by character, word or line using a preset: fade in, blur in, slide up or scale up. The words are real text in the page from the start.
Optional, and kept apart.
Nothing here is included in a project unless you add it, and the plain component it builds on is unchanged. This effect is decoration: it is hidden from screen readers, stands still for visitors who prefer reduced motion, and can be paused. Use Still on a preview to see that version.
import { TextAnimate } from "@rdloom/react";
export default function TextAnimateBasicExample() {
return (
<div className="flex w-full justify-center">
<TextAnimate className="text-2xl font-semibold">Words that arrive one at a time</TextAnimate>
</div>
);
}Installation
npx rdloom add text-animateCopies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes.
It also adds rdloom-motion.css next to your tokens and imports it from the tokens file, once: no setup, and no inline styles. The plain components you already use are untouched.
Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/text-animate.jsonWorks, but without upgrade tracking, and you import the motion CSS yourself.
Usage
import { TextAnimate } from "@rdloom/react";
<div className="flex w-full justify-center">
<TextAnimate className="text-2xl font-semibold">Words that arrive one at a time</TextAnimate>
</div>Presets
import { TextAnimate } from "@rdloom/react";
export default function TextAnimatePresetsExample() {
return (
<div className="flex w-full flex-col items-center gap-3 text-lg font-medium">
<TextAnimate animation="fadeIn">Fade in</TextAnimate>
<TextAnimate animation="blurIn" delay={0.2}>
Blur in
</TextAnimate>
<TextAnimate animation="slideUp" delay={0.4}>
Slide up
</TextAnimate>
<TextAnimate animation="scaleUp" delay={0.6}>
Scale up
</TextAnimate>
</div>
);
}By character
import { TextAnimate } from "@rdloom/react";
// Keep character animation to a few words: the total time grows with every letter.
export default function TextAnimateByCharacterExample() {
return (
<div className="flex w-full justify-center">
<TextAnimate by="character" animation="slideUp" stagger={0.04} className="text-3xl font-bold">
Hello there
</TextAnimate>
</div>
);
}API Reference
Defined by the spec. Components also accept the props of the React Aria component they wrap.
| Prop | Type | Default |
|---|---|---|
childrenrequiredThe text. In line mode, each new line (a newline character) is one unit. | string | none |
byWhat is animated one after another. | "character" | "word" | "line" | "word" |
animationThe preset each unit plays. | "fadeIn" | "blurIn" | "slideUp" | "scaleUp" | "fadeIn" |
delaySeconds before the first unit starts. | number | 0 |
durationSeconds each unit takes. | number | 0.5 |
staggerSeconds between one unit starting and the next. | number | 0.05 |
whenInViewWaits until the text scrolls into view before playing. | boolean | false |
isPausedStops the animation and shows the finished text. Moving content that lasts more than five seconds should be stoppable. | boolean | false |
Accessibility
Role text, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.
Keyboard
Not interactive.
Screen readers announce
- The full text is read once; the animation is not announced
What your code must do
- The full text is present as visually hidden text, so assistive technology reads it once and never character by character
- The animated copy is hidden from assistive technology
- With no JavaScript, or with reduced motion, the text is shown at once
- Decoration only: the animated layers are hidden from assistive technology and never take focus
- Stands still for visitors who ask for less motion (prefers-reduced-motion), and can also be shown still with the rdm-still class or isPaused
- In forced-colors (high contrast) mode the text is drawn in the system colours
- Does not flash: nothing changes more than three times in a second (WCAG 2.3.1)
- Optional: it is a separate component, so projects that do not add it carry none of its code
Guidelines
Use it when
- A heading or short intro that should arrive with some life
- Staggering a short list of words
Avoid it when
- Long passages, especially by character
- Text that changes often
Don't
- Animating by character on text that will be read aloud
- A very long total time: delay plus stagger times the number of units should stay short
Design tokens
The semantic tokens this component uses. Change them once and every component follows; see Design tokens.
--rd-color-text-default--rd-color-text-muted