Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Text

Pro

Mask Reveal Text for React

Text revealed by a panel that wipes across it, covers it, then slides away. For React with Base UI, when a headline should arrive in one decisive cut.

Framework

Mask Reveal Text hides the text behind a solid panel and wipes it in: the panel sweeps across from one side until it covers the text, holds for a beat, then leaves by the other side, and the text is there behind it. It plays once, as soon as the page shows it or once it scrolls into view.

Use it for a hero headline, a section title or a launch line that should arrive in one cut rather than letter by letter. For a wipe the pointer controls, use Text Reveal; for words that fade in one by one, Blur Text. The text itself never moves, so it stays crisp: the panel is a clip-path animation and the text is held hidden until the panel covers it, both CSS keyframes the install adds to your stylesheet, with no animation library. With reduced motion the text is simply there.

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Usage

import { MaskRevealText } from "@/components/ui/mask-reveal-text";
<h1>
  <MaskRevealText text="Out now" />
</h1>

Demos

Direction

direction is the side the panel comes in from; it leaves by the opposite one. start and end follow the text's own reading direction, so Arabic or Hebrew text has start on the right, while a Latin word on a right-to-left page still starts on the left; top and bottom sweep down and up.

Preview width

Sequence

delay holds a line back, in milliseconds, so a subtitle wipes in after its headline. panelColor takes any CSS colour, such as a theme variable: the panel is your primary colour by default.

Preview width

Accessibility

The text is real text from the start, read by screen readers and selectable; the panel is decoration they skip. The wipe is one movement, never a flash. With reduced motion there's no panel and the text shows as it is.

FAQ

Is the text visible before the panel arrives?

No. The text stays hidden until the panel fully covers it, so it never shows, then vanishes, then shows again. Before the wipe the space is simply empty, the size of the text, so nothing around it moves.

How long does the wipe take?

duration is the whole wipe, 1200 ms by default: the panel covers the text by its middle, holds briefly, and is gone by its end.

When does it play?

As soon as the page shows it, by default, from CSS alone. Pass trigger="view" to wait until at least a quarter of the text is in view, for a line further down the page.

Does it work on text that wraps?

Yes. The panel covers the text's whole box, so several lines are revealed in one sweep. For a short line in a paragraph, keep it to a phrase: the effect is a block.

Can it play again?

Give it a new key and React renders it fresh, so it plays again from the start, such as after the text changes.

What happens with reduced motion?

The panel never appears: the text is there from the start.

API Reference

MaskRevealText

<span> data-slot="mask-reveal-text"

PropType
textstring

The text.

delay?number

The wait before the panel comes in, in milliseconds. @default 0.

direction?"start" | "end" | "top" | "bottom"

The side the panel comes in from; it leaves by the opposite one. start and end follow the text's own reading direction.

Type
"start" | "end" | "top" | "bottom"
Default
"start"
duration?number

The whole wipe, in and out, in milliseconds: the text shows at its middle, under the panel.

Default
1200
panelColor?string

The panel's colour, any CSS colour. @default "var(--primary)".

trigger?"mount" | "view"

When it plays: as soon as it's on the page, or once it scrolls into view.

Type
"mount" | "view"
Default
"mount"
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AttributeType
data-view?string

"in" when visible is true, otherwise "out".

CSS variableType
--mask-reveal-text-colorstring

The panel's colour (var(--primary)).

--mask-reveal-text-delaystring

The wait before the panel comes in (0ms).

--mask-reveal-text-durationstring

The whole wipe, in and out (1200ms).

--mask-reveal-text-tostring
All 97 text effects