Components / Motion / Word Rotate

Word Rotate beta

One word in the sentence keeps changing: a vertical carousel of the words that fit.

Preview

Built for dashboards, docs, pricing pages and settings.

<p style="font-size:24px;font-weight:600;letter-spacing:-.02em;line-height:1.35">
  <span style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)">Built for dashboards, docs, pricing pages and settings.</span>
  <span aria-hidden="true">Built for <span class="k-wrot" data-wrot><span class="k-wrot-in"><span>dashboards</span><span>docs</span><span>pricing pages</span><span>settings</span></span></span></span>
</p>
/* KATA Word Rotate — a stack of words, stepped. */
.k-wrot{display:inline-block;height:1.26em;overflow:hidden;vertical-align:bottom;text-align:start}
.k-wrot-in{display:flex;flex-direction:column;transition:transform .55s cubic-bezier(.65,0,.2,1)}
.k-wrot-in span{height:1.26em;line-height:1.26em;white-space:nowrap;color:var(--k-accent-ink);font-weight:650}
@media (prefers-reduced-motion:reduce){.k-wrot-in{transition:none}}
// KATA Word Rotate — steps the stack; wraps without a visible rewind.
document.querySelectorAll('[data-wrot]').forEach(function (el) {
  var inner = el.querySelector('.k-wrot-in');
  var words = inner.children.length;
  if (words < 2) return;
  inner.appendChild(inner.children[0].cloneNode(true));
  var i = 0;
  setInterval(function () {
    i++;
    inner.style.transform = 'translateY(-' + (i * 1.26) + 'em)';
    if (i === words) {
      setTimeout(function () {
        inner.style.transition = 'none';
        inner.style.transform = 'translateY(0)';
        i = 0;
        requestAnimationFrame(function () { requestAnimationFrame(function () { inner.style.transition = ''; }); });
      }, 580);
    }
  }, 2100);
});

Installation

CLI

node kata-ui.mjs add word-rotate

Writes the part’s CSS and JS into your project. New to the CLI? See the CLI doc.

Manual

  1. Load tokens.css once, before any part.
  2. Copy the CSS tab into your stylesheet.
  3. Copy the HTML where it belongs. The part has a script — include it after the markup; it initializes itself.

Usage

For the hero sentence with a variable in it — "Built for dashboards / docs / pricing pages". The words sit in the markup as a stack; the script steps the stack every two seconds and loops it cleanly. Keep the words one length family apart at most, or the sentence breathes oddly as it changes.

Accessibility

Screen readers should meet one sentence, not five: the rotating stack is aria-hidden and a visually-hidden static version carries the meaning. The rotation pauses under prefers-reduced-motion, leaving the first word standing.

Anatomy

The public surface of this part, read from its own source. Class names are the API — the CSS tab above is the full contract.

.k-wrotclass
.k-wrot-inclass
data-wrotdata hook
aria-hiddenARIA

Related parts