Skip to the content

Word loop

A heading with one word that turns. The word sits in a slot on the heading's own baseline, and every few seconds it gives way to the next one of a list: the letters of the word that leaves rise one after the other out of a mask, the letters of the next one rise from below on the same beat, and the slot changes width at the same time, so the rest of the line glides to its new place instead of jumping.

Become a member to unlock the full effect today.

Join now

Already a member? Sign in

Documentation

  1. Copy to Webflow

    Add Geist and Geist Mono to your site's fonts (Site settings, Fonts, Google Fonts) before pasting: Webflow removes any font your site has not installed.

  2. Add custom CSS

    The slot has no width of its own at rest: it is as wide as its word, so nothing is frozen and nothing has to be styled. Leave the heading and the span without overflow: hidden and without text-wrap: balance: the first would cut the rule, the second would move the line breaks at every word. Keep the word on a line it cannot push to the next one, as the three lines of the preview do.
  3. Add custom JS

  4. Use it on your own elements

    Custom attributes
    Select the element on the canvas and open the Settings panel. Under Custom attributes, add a pair: the name on the left, the value on the right.
    Custom attributeWhat it does
    data-word-loop Marks the word that cycles: a span around one word of a heading. It takes no value: leave the value field empty. The text of the span is the first word, and the script builds the slot, the letters and the rule inside it; the heading around it stays as it is.
    data-word-loop-words The other words of the list, separated by |, on the marked span: printers|architects|binders. The span shows its own text first, then each of them in turn, and starts again. In code the words can also be written as children of the span, one element per word. With neither, the word stands still over its rule. [ Optional ]
    data-word-loop-state Written by the engine on the span: idle while a word rests and the clock runs, changing during a change, paused off screen, under the pointer or in a hidden tab, static under reduced motion. Never written by hand. [ Optional ]
    Settings
    Every setting is a custom attribute too, added the same way and on the same element. An attribute always wins over the defaults written in the code.
    AttributeDefaultWhat it is
    data-word-loop-color inherit Ink of the word that cycles; inherit keeps the colour of the heading. Options: inherit, or any CSS colour to set the word apart from the rest of the line; taken out of this block, --word-loop-color on the span takes over.
    data-word-loop-rule #ffab1a Colour of the rule under the word. Options: any CSS colour; taken out of this block, --word-loop-rule on the span takes over.
    data-word-loop-interval 2.4 Time from the start of one change to the start of the next, in seconds; the first word leaves after half of it, and a word always rests at least 0.3 s.
    data-word-loop-duration 0.7 Time one letter takes to travel, and the slot to change width, in seconds.
    data-word-loop-stagger 0.03 Delay between two neighbouring letters, left to right, in seconds; the whole cascade never lasts longer than duration.
    data-word-loop-direction up Way the letters travel. Options: up (the old word rises out, the new one rises from below), down (the reverse).
    data-word-loop-rule-width 0 Thickness of a rule under the word, in px, 0 by default.
    data-word-loop-pause-on-hover 0 Whether the loop waits while a mouse is on the word. Options: 0 (it never waits, the default), 1 (it waits, and starts again when the pointer leaves).

What it does

Word loop is a text animation for Webflow and vanilla JavaScript, with no library. Also called rotating text animation, rotating words or text loop.

A heading with one word that turns. The word sits in a slot on the heading's own baseline, and every few seconds it gives way to the next one of a list: the letters of the word that leaves rise one after the other out of a mask, the letters of the next one rise from below on the same beat, and the slot changes width at the same time, so the rest of the line glides to its new place instead of jumping. A thin rule under the word is wiped off and drawn again from the left at each change. Each word is measured as it comes, once the fonts are in, and at rest the slot has no width of its own, so nothing is ever frozen at a stale size. The loop waits while the heading is off screen, in a hidden tab, and while the pointer is on the word; a click or a tap moves on at once. A word longer than its line breaks inside the slot instead of pushing the page wider. Under reduced motion the word still changes, at once, and the rule stands. Pattern type rotating text, word rotate, flip words, text loop.

Updated

Questions

Select the word in the Heading, wrap it in a span, and add two custom attributes to that span: data-word-loop, with no value, and data-word-loop-words with the other words separated by |, for instance data-word-loop-words="printers|architects". The text of the span is the first word. In the Designer the heading reads with that first word, since the canvas runs no Embed.

No. There is no library and no build: the letters are split into masked cells and moved with the Web Animations API. The width of each word is measured as it comes, once the fonts are in, and the slot is animated to it so the rest of the line glides.

Set data-word-loop-interval, the time in seconds from the start of one change to the start of the next, 2.4 by default. Under 1.5 the heading is hard to read, and a higher value leaves each word on show longer. data-word-loop-duration, 0.7 by default, is the time one letter takes to travel and the slot to change width.

Because the engine animates a width, not a line break: when the longest word no longer fits, the browser moves it to the next line in one step. Give the cycling word a line that holds its longest entry, a line of its own for instance. Also leave text-wrap: balance off the heading, or every line moves at every word.

Yes. The span holds the word on show as plain text and the animated letters are hidden from it, so the heading is read as one sentence and never letter by letter. The text is not a live region, so a change of word is not announced.