Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Text

Free

Shimmering Text for React

Text with light running through it, each character brightening in turn. For React with Base UI, when a status is working or a headline should glint.

Framework

Shimmering Text runs a band of light through a line: each character brightens to the light's colour and back as it passes, start to end, then the light rests a moment and passes again. Characters can also lift a little in step, so the light seems to ripple through them.

Use it for a status that's still working, "Thinking…" or "Reading 12 files…", or for a short headline that should catch the eye without moving. For colour that keeps flowing as a gradient, use Gradient Text; for each letter cycling through colours of its own, Colourful Text; for metal, Chrome Text. The light is a CSS colour keyframe animation the install adds to your stylesheet, run on each character and delayed by its share of the text, with no animation library. With reduced motion the text rests in its base colour.

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

Usage

import { ShimmeringText } from "@/components/ui/shimmering-text";
<p>
  <ShimmeringText text="Thinking it through…" />
</p>

Demos

Wave

wave lifts each character a little as the light reaches it, and sets it down as the light moves on, for a headline that should feel alive.

Preview width

Colors

baseColor is the text where the light isn't, and shimmerColor the light itself: any CSS colours, your theme's variables included. By default they're var(--muted-foreground) and var(--foreground), so the light is brighter than the text in light and dark mode alike.

Preview width

Duration

duration is one pass of the light across the text and the short rest before the next, 2000 ms by default. A quick pass suits a small status; a slow one, a quiet hero.

Preview width

Accessibility

Screen readers read the text once, as plain text, from a visually hidden copy; the characters the light runs through are hidden from them. Words wrap whole, and the line keeps its direction on a right-to-left page. Between passes the text is in its base colour, so check that colour's contrast against the page: the default, the theme's muted foreground, is made for text. With reduced motion the light doesn't run.

FAQ

Does a longer text shimmer more slowly?

No. Each character waits for its share of the text before it brightens, so the light crosses a word and a sentence in the same time, duration, and the band of light is always about two fifths of the line wide.

Can I use it for a loading status?

Yes, that's what it's best at. Put it in an element with role="status", such as <p role="status"><ShimmeringText text="Thinking…" /></p>, so screen readers announce the status when it appears, and replace it with the result when the work is done.

How do I keep my text's own colour?

Pass baseColor="currentColor": the text takes the colour of the element around it, and the light passes in shimmerColor. Pick a light that differs enough from that colour to be seen.

Which way does the light run?

From the start of the text to its end: left to right in English, right to left in Hebrew. Arabic letters join, and splitting a word into characters breaks the joins, so keep it to scripts whose letters stand apart.

Does a constant shimmer cost much?

Little: it changes the colour of a few characters at a time, with no JavaScript and no layout. Keep it to a line or a label rather than a paragraph.

What happens with reduced motion?

The light stops and the text stays in its base colour, readable as it is. With wave, the characters stay on the line.

API Reference

ShimmeringText

<span> data-slot="shimmering-text"

PropType
textstring

The text. Its line breaks (\n) are kept.

baseColor?string

The text's colour where the light isn't, any CSS colour.

Default
"var(--muted-foreground)"
duration?number

One pass of the light across the text, the short rest before the next one included, in milliseconds.

Default
2000
shimmerColor?string

The colour of the light as it passes each character, any CSS colour.

Default
"var(--foreground)"
wave?boolean

Each character also lifts a little as the light passes it. @default false.

Default
false
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

Forwarded to the part.

CSS variableType
--shimmering-text-colorstring

The text's colour where the light isn't.

--shimmering-text-durationstring

One pass of the light and its rest (2s).

--shimmering-text-shimmer-colorstring

The light's colour.

All 97 text effects