Text✨ Premium

Word by Word

Words emerge one after another with a fade and a gentle rise — dramatic reveal built on a single CSS animation and vanilla JS.

JSCSSWords

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Text has 56 effects, including 4 free. Explore the category →

3 usage examples

Hero headline — Title that builds word by word — Word by Word example 1

① Hero headline — Title that builds word by word

WhenThe homepage or a campaign landing page loads and the main headline reveals its words one by one to capture attention from the very first second.
WhyThe word-by-word suspense keeps the eye on the headline for the full animation — 1.5 to 2 s of attention retention with no decorative element needed.
Settings0.3 s delay between words, animation-duration 0.7 s, font-size 3.5–5 rem, translateY start 30 px to accentuate the rise.
Editorial pull quote — Standout quote in an article or report — Word by Word example 2

② Editorial pull quote — Standout quote in an article or report

WhenA strong quote (interview, conference, case study) needs to stand out visually in an article or long-form sales page — the word-by-word reveal gives it weight without a background animation.
WhyThe animation forces linear reading: the visitor cannot scan the sentence at a glance, which improves recall of the key message.
Settings0.2 s delay, 0.5 s duration, font-size 1.8–2.5 rem, translateY 12 px — subtle entrance to stay in the editorial register.
Pitch slide — High-impact keynote opening or closing statement — Word by Word example 3

③ Pitch slide — High-impact keynote opening or closing statement

WhenThe last slide of a pitch deck or keynote displays the closing statement: each word lands one by one, giving the audience time to absorb the message before the sentence is complete.
WhyIn a presentation, slowness is a feature — word-by-word imposes silence and focus, whereas text already on screen gets skimmed past. The animation naturally justifies and exploits the 0.35 s delay.
Settings0.35 s delay, 0.7 s duration, font-size 3–4 rem, translateY 30 px — oratory pace, designed for full-screen projection.

How it works

The effect relies on a single CSS animation, wordAppear, that transitions each word from opacity:0; transform:translateY(20px) to its final state in 0.6 s using an ease curve and fill-mode:forwards. Each word lives in a <span> with an inline animation-delay computed by the JS function splitWords: the first word at 0 s, then +0.3 s per additional word.

The function splitWords(el, text, delay) splits the string on whitespace, empties the target element, creates one <span> per word with its computed animation-delay (i * delay + 's'), and inserts the nodes into the DOM. As soon as they are inserted, the CSS rule .text-word-by-word span takes over and fires the animations in cascade — no further JS is needed for the initial render.

The Replay button clears the element (innerHTML = ''), waits 50 ms for the browser to flush computed styles and reset the animation cycle, then calls initWordByWord() again. The delay is essential: removing and immediately reinserting spans without a pause prevents the browser from restarting the @keyframes.

Code note: in the original version, replayWordByWord and splitWords are defined inside the IIFE and not exposed globally — the onclick button will not work without adaptation (see FAQ). The initial animation, however, works in pure CSS as soon as the <span> elements are in the DOM.

Accessibility

  • prefers-reduced-motion absent: the effect does not check the system preference — all words animate even if the user has requested reduced motion. To cover this case, add: @media (prefers-reduced-motion: reduce) { .text-word-by-word span { animation: none; opacity: 1; transform: none; } }.
  • Each word's text is in the DOM in plain text — screen readers read the full sentence without waiting for the animation to finish.
  • The Replay button is a native <button> element, keyboard-focusable (Tab · Enter · Space) with no extra configuration.
  • White text on a dark background (#0a0a0f) provides a contrast ratio above 10:1 — compliant with WCAG AA and AAA.
  • No aria-* attributes or role are set on the container: add aria-label if the animated text is the only accessible content in the section.

Browser compatibility

Requires CSS3 @keyframes and animation-fill-mode — available in all modern browsers since 2013. Zero external dependencies, no canvas required.

Chrome 26+✓ Full
Firefox 16+✓ Full
Safari 9+✓ Full
Edge 12+✓ Full
Mobile iOS✓ Full
Android Chrome✓ Full

If CSS animations are disabled (high-contrast mode on Windows, old browser), all spans default to <code>opacity:0</code> — text disappears. To guarantee readability without animation, add <code>@media (prefers-reduced-motion: reduce) { .text-word-by-word span { opacity: 1; transform: none; animation: none; } }</code>.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<div class="demo-preview">
  <span class="demo-text text-word-by-word" id="wordByWordText">
    <span style="animation-delay: 0s">WORD</span>
    <span style="animation-delay: 0.3s">BY</span>
    <span style="animation-delay: 0.6s">WORD</span>
  </span>
  <button class="replay-btn" onclick="replayWordByWord()">Replay</button>
</div>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
delay (splitWords arg) 0.3 Seconds between consecutive words appearing. 0.5 s = dramatic pace; 0.1 s = rapid cascade.
animation-duration (.text-word-by-word span) 0.6s Entry duration per word. 0.9 s = very soft fade; 0.25 s = sharp snap.
translateY initial (.text-word-by-word span) 20px Start height before the rise. 0 px = pure fade with no movement; 40 px = dramatic entry from below.
animation-timing-function ease Animation curve. ease-out for a natural deceleration; cubic-bezier(0.22,1,0.36,1) for an elastic overshoot.
font-size (.demo-text) 2.5rem Text size. 4–6 rem for a full-screen hero; 1.5 rem for a subtitle.
font-weight (.demo-text) 800 Font weight. 700 = standard bold; 900 = black for a very assertive typographic style.
letter-spacing (.demo-text) -0.02em Letter spacing. Positive (0.1 em) for a spaced all-caps look; more negative (−0.05 em) for a very tight headline.

FAQ

Replace the 'WORD BY WORD' string passed to splitWords() inside initWordByWord(): the function automatically splits into words and computes the animation-delay values. You can also edit the <span> elements directly in the HTML, adjusting delays in 0.3 s increments.
replayWordByWord is defined inside the IIFE and is not globally accessible. Expose it before closing the IIFE: window.replayWordByWord = replayWordByWord;. Also make sure splitWords is defined in the global scope or inside the IIFE before it is called.
Yes. Give each .text-word-by-word container a distinct id and call splitWords(el, text, delay) on each one. Every instance is self-contained — it only touches its own element and its own <span> nodes.