bx

shimmer

Utilities for adding a shimmer effect to text elements.

Generating response…

Thinking…
Oliver is typing…
tsx

shimmer is a highlight that sweeps horizontally across text. Typical pattern: showing that an AI model is generating a response, or that a job is waiting for a result.

Built on background-clip: text and an animated gradient: pure CSS, no JS. The highlight derives from currentColor, so it adapts to any color without configuration.

Disabled automatically when the user prefers reduced motion (prefers-reduced-motion: reduce).

Usage

ClassStyles
shimmer background-clip: text + animation: tw-shimmer var(--shimmer-duration, 2s) linear infinite
shimmer-once animation-iteration-count: 1: a single sweep (good for a reveal after streaming).
shimmer-reverse animation-direction: reverse.
shimmer-none Disables the shimmer (responsive variant: md:shimmer-none).
--shimmer-color Highlight color (default: derived from currentColor). Set it inline: style="--shimmer-color: #60a5fa".
--shimmer-duration Duration of one sweep. Default 2s. E.g. style="--shimmer-duration: 1000ms".
--shimmer-spread Width of the band. Default calc(3ch + 40px).
--shimmer-angle Tilt angle. Default 20deg.

With Marker

The shimmer composes with any component that renders text. A typical pattern: a Marker that shows a live status while the assistant is working.

Thinking…
tsx
<Marker role="status">
  <MarkerIcon><Spinner /></MarkerIcon>
  <MarkerContent className="shimmer">Thinking…</MarkerContent>
</Marker>

Color

Set the highlight with --shimmer-color (accepts any CSS color).

Generating response…

Generating response…

tsx
<p className="shimmer text-blue-500" style={{ "--shimmer-color": "#60a5fa" } as any}>Generating response…</p>

Duration

Set --shimmer-duration for the duration of one sweep. Default 2000ms.

Generating response… (default 2000ms)

Generating response… (1000ms)

Generating response… (4000ms)

tsx
<p className="shimmer" style={{ "--shimmer-duration": "1000ms" } as any}>Generating response…</p>

Spread

Set --shimmer-spread for the width of the highlight band.

Generating response… (default)

Generating response… (spread 8rem)

tsx
<p className="shimmer" style={{ "--shimmer-spread": "8rem" } as any}>Generating response…</p>

Angle

Set --shimmer-angle for the tilt angle. Default 20deg.

angle 0°

angle 45°

angle 90°

tsx
<p className="shimmer" style={{ "--shimmer-angle": "45deg" } as any}>Generating response…</p>

Reverse

shimmer-reverse reverses the direction of the sweep.

Generating response…

tsx
<p className="shimmer shimmer-reverse">Generating response…</p>

Play Once

shimmer-once plays a single sweep instead of looping, which is good for a reveal at the end of streaming. Combine it with --shimmer-duration to control the duration of the reveal.

Response generated.

tsx
<p className="shimmer shimmer-once" style={{ "--shimmer-duration": "1100ms" } as any}>Response generated.</p>

Disabling the Shimmer

shimmer-none disables the effect and renders the text normally. Useful as a responsive variant.

tsx
<p className="shimmer md:shimmer-none">Generating response…</p>

Reduced Motion

When the user prefers reduced motion, the animation is disabled automatically and the text renders normally. Nothing to configure.

RTL

The sweep follows the reading direction (left→right in LTR, right→left in RTL) with no extra class. Use shimmer-reverse to flip it manually.

جاري إنشاء الرد…