Per Character Rise
No blur, no scale, no depth: each character starts below its baseline and rises into place. The restraint is the point. Blur and scale draw attention to the motion, while a short vertical rise reads as the type simply arriving.
At headline sizes the per-letter stagger is short enough to feel like one gesture. On body-sized text the same effect reads as a typewriter, which is why the default stagger is stated in milliseconds and left to the caller to lower.
Usage
<template>
<div class="flex w-full items-center justify-center py-10">
<MPerCharacterRise
class="text-center text-3xl font-bold text-highlighted"
:stagger="22"
text="Read it one letter at a time"
/>
</div>
</template>
Splitting is by Unicode code point (Array.from), not by UTF-16 code unit, so an
emoji or a rare CJK character is not torn into two broken halves.
Customize
Customize
Props
| Prop | Type | Default | Description |
|---|---|---|---|
textrequired | string | - | The copy to reveal, split into one element per character. |
stagger | number | 24 | Per-character stagger, in milliseconds. |
delay | number | 0 | Delay before the first character starts, in milliseconds. |
triggerOnView | boolean | false | Wait for the element to scroll into view before playing. |
class | string | - | Extra classes for the root element. |
Accessibility
The sentence is announced once through an sr-only span; every rising glyph is
aria-hidden. Reading the string character by character would be unusable, and
an aria-label on the root would not be exposed because a span has no role.
Spaces become no-break spaces inside their own inline-block. A plain space would collapse at the edge of the block and close the gap between words, while a no-break space keeps the gap and still allows the parent to wrap between characters.
Reduced motion collapses the transition duration instead of skipping the animation. Removing the animation would leave every glyph at its hidden offset forever, because motion-v only writes values that actually animate.
Performance
- Only
opacityandtransformchange, so the rise is compositor-only. - One observer per component, not per character, and it unobserves after the first intersection.
- Long strings produce one element per character. That is fine for a headline and wasteful for a paragraph; use Blur Out Up or Depth Parallax Words for prose.