Motion Text

New

Word-by-word text animation for reveal, gradient, and shimmer moments.

Usage

DtMotionText animates text word by word. Pass text and the effect plays as soon as the component mounts, using gradient-in unless you set animation-mode.

Every effect except shimmer works on whole words, never individual characters. Words animate in reading order, each starting a moment after the one before it. shimmer instead sweeps one dimmed band left to right across the whole text, so it reads well even on a single word. The gradient effects place one continuous purple-to-orange gradient behind all of the words, so each word shows its own slice of the same sweep rather than a gradient of its own. The gradient is the --dt-color-gradient-orange-red-magenta-purple token, a horizontal span of the Ai gradient used by Ai surfaces and borders.

Animation Modes

Mode Effect
gradient-in (default) Each word fades in showing its slice of the gradient, then its text color fades in over it.
fade-in Each word fades in.
slide-in Each word fades in while rising into place.
slide-in-gradient The slide-in motion combined with the gradient-in color reveal.
gradient-sweep Text starts solid. Each word fades to the gradient, holds, then fades back to its text color.
shimmer A dimmed band sweeps left to right across the whole text.
none No animation. The text renders at rest.

Select a mode to play it. Loop is on, so each effect keeps repeating; turn it off to watch a single play.

Speed Control

speed scales every timing in the effect proportionally. The default, 300, plays each effect at its designed timing. Lower values are faster and higher values are slower: 100 runs at 0.3× the designed timing, 200 at 0.6×, 400 at 1.5×, and 500 at 2.1×.

Manual Control

Set :auto-start="false" to start the effect on your own trigger, then drive it with the start(), pause(), resume(), reset(), and skipToEnd() methods. Switching auto-start to true later also starts the effect.

Until start() is called, the reveal modes (gradient-in, fade-in, slide-in, and slide-in-gradient) keep the text hidden, while gradient-sweep and shimmer show the text at rest. reset() returns every word to that starting frame, and skipToEnd() shows the text at rest immediately.

Looping Animation

Set loop to repeat the effect continuously. When a cycle finishes, the text holds at rest for a moment, then every word resets together and the cycle plays again. The hold is fixed, so the length of each cycle depends on how many words there are. For a six-word line at speed 300, the reveal modes repeat every 2 seconds and gradient-sweep every 2.65 seconds. shimmer repeats back to back every 3 seconds, whatever the length of the text.

Each cycle emits start when it begins and complete when its last word settles.

Using Slots

You can pass the text through the default slot instead of the text prop.

  • shimmer renders the slot as-is, so markup such as <strong> and live updates, like streamed text or a changing name, are kept.
  • The word-by-word modes read the slot once as plain text and split it into words, so markup inside the slot isn't preserved.

Whitespace between words, including line breaks, is kept, so white-space: pre-wrap on the component still applies.

Accessibility

Reduced Motion Support

By default, DtMotionText follows the user's prefers-reduced-motion system setting. When reduced motion is requested, the text renders at rest with no movement or gradient, and the start and complete events still fire.

Set :respects-reduced-motion="false" only when the motion itself carries meaning. The effect then plays even when the user has asked for reduced motion.

Screen Reader Support

Each word is real text separated by real spaces, so screen readers read the sentence as written. When the visible text isn't a good spoken equivalent, such as text with emoji or symbols, provide screen-reader-text:

ARIA Attributes

DtMotionText sets these attributes automatically:

  • aria-live="polite" while the effect is animating, and aria-live="off" otherwise.
  • Without screen-reader-text, the animated words stay available to assistive technology at all times, including while they animate.
  • With screen-reader-text, the component adds an aria-label and a visually hidden copy of that text, and marks the animated words aria-hidden="true".

Best Practices

  1. Match the effect to the moment: Reserve the gradient modes (gradient-in, slide-in-gradient, and gradient-sweep) for AI-generated text inside product UI. Don't use them on brand headlines or hero sections (see Gradient). Use fade-in or slide-in for quieter reveals and body text, and a looping gradient-sweep or shimmer for thinking and loading states.
  2. Keep the gradient brief: The lightest gradient stops fall below 4.5:1 contrast on light surfaces and the darkest below 3:1 on dark surfaces. The reveal modes show the gradient only briefly before the text settles to solid ink, so avoid holding text on the gradient where people need to read it.
  3. Keep the text short: Every word adds to the stagger, so long passages take longer to finish. Reserve effects for short phrases.
  4. Start with the default speed: 300 is the designed timing. Use 200 when the effect needs to finish quickly, and 400 or 500 for slower, more deliberate moments.
  5. Don't overuse: Too many animated elements on one screen compete for attention.
  6. Test with reduced motion: Make sure your UI still reads well when the text renders at rest.
  7. Provide screen reader text: If the text includes emoji or special characters, include a spoken alternative.

Vue API

import { DtMotionText } from '@dialpad/dialtone-vue';

Slots

Name
Type
default

Props

Name
Default
Type
animationMode
'gradient-in'
"gradient-in" | "fade-in" | "slide-in" | "slide-in-gradient" | "gradient-sweep" | "shimmer" | "none"

The animation mode to use for the text reveal. none renders the text without animation.

autoStart
true
"true" | "false"

Whether to start animation automatically when component is mounted.

loop
false
"true" | "false"

Whether to loop the animation continuously.

respectsReducedMotion
true
"true" | "false"

Whether to respect the user's prefers-reduced-motion system setting.

screenReaderText
''
string

Alternative text for screen readers. If provided, this will be announced instead of the animated text.

speed
300
"100" | "200" | "300" | "400" | "500"

Animation speed. 300 plays the motion spec as designed; lower values are faster.

text
''
string

The text content to animate.

Events

Name
Type
complete

Emitted when the animation completes, and at the end of each looped cycle.

pause

Emitted when the animation is paused.

progress
{ wordsComplete: number, totalWords: number, progress: number }

Emitted as each word finishes animating.

resume

Emitted when the animation resumes.

start

Emitted when the animation starts, and at the start of each looped cycle.

Motion Text documentation last updated Tuesday, October 27, 2026