Menu

Text shimmer

Added in 1.7.0

A highlight that sweeps across a short label while an agent thinks or a task runs.

Basic example

Add .text-shimmer to a short label that reports work in progress. The label fades in, then the text is dimmed and a band of full color moves across it from start to end.

Thinking…
<span class="text-shimmer">Thinking…</span>

Colors

The shimmer is a mask, so the text keeps its own color. Combine it with any text color utility.

Thinking…Thinking…Thinking…Thinking…
<div class="d-flex flex-column gap-2">
  <span class="text-shimmer">Thinking…</span>
  <span class="text-shimmer text-secondary">Thinking…</span>
  <span class="text-shimmer text-primary">Thinking…</span>
  <span class="text-shimmer text-green">Thinking…</span>
</div>

With a loader

Put an empty .text-shimmer-loader before the label when the text alone is too quiet. It is a small spinner drawn by the element alone. It sits inside the shimmer, so it takes the color of the text and dims with it.

Thinking…Generating a reply…
<div class="d-flex flex-column gap-2">
  <span class="text-shimmer" role="status">
    <span class="text-shimmer-loader" aria-hidden="true"></span>Thinking…
  </span>
  <span class="text-shimmer text-primary" role="status">
    <span class="text-shimmer-loader" aria-hidden="true"></span>Generating a reply…
  </span>
</div>

The loader is a 1em box, so it follows the font size. Set --tblr-text-shimmer-loader-size and --tblr-text-shimmer-loader-border-width to resize the ring inside it, --tblr-text-shimmer-loader-duration to change its speed, --tblr-text-shimmer-loader-opacity to change how faint the ring behind the arc is, and --tblr-text-shimmer-loader-margin to change the space before the label.

Speed and contrast

Set --tblr-text-shimmer-duration to change how long one sweep takes, and --tblr-text-shimmer-opacity to change how much the text is dimmed between sweeps. The fade-in is 320ms by default; change it with --tblr-text-shimmer-fade-duration.

Fast sweepSlow sweepLess contrast
<div class="d-flex flex-column gap-2">
  <span class="text-shimmer" style="--tblr-text-shimmer-duration: 1s">Fast sweep</span>
  <span class="text-shimmer" style="--tblr-text-shimmer-duration: 4s">Slow sweep</span>
  <span class="text-shimmer" style="--tblr-text-shimmer-opacity: 0.7">Less contrast</span>
</div>

In a chat

Use the shimmer in place of a reply that has not arrived yet, next to the avatar of the assistant.

AIReading the file…
<div class="d-flex align-items-center gap-2">
  <span class="avatar avatar-xs">AI</span>
  <span class="text-shimmer text-secondary" role="status">
    <span class="text-shimmer-loader" aria-hidden="true"></span>Reading the file…
  </span>
</div>

Accessibility

  • The animation is only a hint. The label itself has to say what is going on, for example "Thinking…" or "Uploading 3 files…".
  • Add role="status" when the label appears while the user waits, so screen readers announce it and any change to it.
  • When the user prefers reduced motion, the sweep stops and the text shows in its full color.

Class reference

Every class this component ships, grouped by what it changes. A name in braces stands for a family — {color} is any base color, {breakpoint} any responsive step.

text-shimmer componentDims the text and sweeps a highlight across it
text-shimmer-loader partA small spinner before the label

CSS

Variables

The component uses local CSS variables on .text-shimmer for real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. Source: core/scss/ui/_text-shimmer.scss.

--text-shimmer-duration: #{$text-shimmer-duration};
--text-shimmer-opacity: #{$text-shimmer-opacity};
--text-shimmer-width: #{$text-shimmer-width};
--text-shimmer-fade-duration: #{$text-shimmer-fade-duration};
--text-shimmer-fade-easing: #{$text-shimmer-fade-easing};
--text-shimmer-loader-size: #{$text-shimmer-loader-size};
--text-shimmer-loader-border-width: #{$text-shimmer-loader-border-width};
--text-shimmer-loader-margin: #{$text-shimmer-loader-margin};
--text-shimmer-loader-duration: #{$text-shimmer-loader-duration};
--text-shimmer-loader-opacity: #{$text-shimmer-loader-opacity};

Sass variables

Override these variables before importing Tabler to change the defaults. Source: core/scss/_variables.scss.

$text-shimmer-duration: 2s;
$text-shimmer-opacity: 0.4;
$text-shimmer-width: 20%;
$text-shimmer-fade-duration: 320ms;
$text-shimmer-fade-easing: cubic-bezier(0.22, 1, 0.36, 1);
$text-shimmer-loader-size: math.div(12em, 14);
$text-shimmer-loader-border-width: 0.1em;
$text-shimmer-loader-margin: math.div(4em, 14);
$text-shimmer-loader-duration: 0.75s;
$text-shimmer-loader-opacity: 0.25;