motion-text-mask
Mask-clip reveal primitive. Clips slotted content behind an overflow:hidden boundary and springs it upward into view.
This is the same technique used inside motion-headline, exposed as a standalone composable wrapper for any content.
Preview
Import
import 'motion-components/motion-text-mask' // just this one
import 'motion-components' // or the whole libraryUsage
<motion-text-mask>
Your headline or any block content
</motion-text-mask>Composing with motion-stagger
Wrap each line or word in its own motion-text-mask inside a motion-stagger to build a custom headline reveal without using motion-headline.
<motion-stagger interval="0.1">
<motion-text-mask>Craft</motion-text-mask>
<motion-text-mask>award-winning</motion-text-mask>
<motion-text-mask>motion.</motion-text-mask>
</motion-stagger>How it works
The host element has overflow:hidden set via Shadow DOM styles and vertical-align:bottom so the clip boundary sits at the text baseline.
An inner div starts at translateY(110%) (the extra 10% prevents sub-pixel bleed-through) and spring-animates to translateY(0%).
The content appears to rise from behind an invisible floor.
Loop
Add loop to rise the text into view, hold, drop it back behind the mask and rise again.
hold sets how long it stays visible, gap how long it stays hidden.
Rises and falls with
<motion-text-mask loop hold="1.4" gap="0.5">the mask</motion-text-mask>
The cycle runs only while the text is on screen, and once is ignored. Add
pause-on-hover to freeze it while the pointer is over the text.
Properties
| Attribute | Property | Type | Default | Description |
|---|---|---|---|---|
| | | number | 0.9 | Spring duration hint in seconds |
| | | number | 0 | Initial delay in seconds before the reveal |
| | | number | 0.2 | IntersectionObserver visibility threshold (0–1) |
| | | boolean | true | Reveal only on first intersection. Ignored with |
| | | boolean | false | Reveal, hold, hide and reveal again on repeat. The cycle runs while the text is on screen |
| | | number | 1.6 | With |
| | | number | 0.5 | With |
| | | boolean | false | Pause the loop while the pointer is over the text, resuming on leave |
JavaScript API
Trigger the text mask programmatically with play() and cancel().
Accessibility
Respects prefers-reduced-motion: when enabled, the mask reveal animates instantly, the text is fully visible and loop never starts.