SWAMP UI / COMPONENTS / SPLIT-FLAP TEXT

Split-Flap Text

like an old train station board

Letters spin through random glyphs and lock into place, one by one. A small moment of mechanical drama for any heading that wants to feel like it just arrived instead of being there all along.

No dependencies
~1.5 KB
Vanilla JS
Click to replay
LIVE PREVIEW
SWAMP UI
click the text to replay ↑

When to use

Reach for it when you have a hero or title that wants more presence, when the page is otherwise calm and you want one moment of mechanical drama, or when you want a click target that gives delight without a full animation.

Skip it when the text is long (more than ~30 chars feels noisy), when the page is already animation-heavy, or when readers need to read fast.

Skip to

1. HTML

Add the class flip to any heading. The data-final attribute holds the text that will lock in.

<h1 class="flip" data-final="Sophie's Swamp">Sophie's Swamp</h1>

2. CSS

Two states: spinning (lime) and locked (cream). Swap the colors for your palette.

.flip { cursor: pointer; }

.flip .ch {
  display: inline-block;
  min-width: .55em;
  text-align: center;
  transition: color .15s;
}

.flip.flipping .ch {
  color: #b6ff5b;   /* spinning: neon lime */
  text-shadow: 0 0 14px rgba(182,255,91,.55);
}

.flip.flipping .ch.locked {
  color: #f3eedd;   /* locked: cream */
  text-shadow: 0 0 20px rgba(82,255,224,.25);
}

3. JavaScript

Drop into a <script> tag at the bottom of your page. Runs once on load. Click any .flip to replay.

// Swamp UI — Split-Flap Text
(function () {
  const POOL = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#@%&*+=°/';
  function rand() { return POOL[Math.floor(Math.random() * POOL.length)]; }

  function splitInto(el, finalText) {
    el.innerHTML = '';
    const chars = [...finalText];
    return chars.map(ch => {
      const s = document.createElement('span');
      s.className = 'ch';
      s.dataset.final = ch;
      s.textContent = (ch === ' ') ? ' ' : rand();
      el.appendChild(s);
      return s;
    });
  }

  function play(el) {
    const finalText = el.dataset.final || el.textContent.trim();
    const spans = splitInto(el, finalText);
    el.classList.add('flipping');

    const STEP = 55;        // ms between random swaps
    const PER_LETTER = 9;   // # of swaps before locking
    const STAGGER = 70;     // ms offset per letter

    spans.forEach((s, i) => {
      const target = s.dataset.final;
      if (target === ' ') { s.classList.add('locked'); return; }
      let swaps = 0;
      setTimeout(function spin() {
        if (swaps >= PER_LETTER) {
          s.textContent = target;
          s.classList.add('locked');
          if (spans.every(x => x.classList.contains('locked'))) {
            setTimeout(() => el.classList.remove('flipping'), 400);
          }
          return;
        }
        s.textContent = rand();
        swaps++;
        setTimeout(spin, STEP);
      }, i * STAGGER);
    });
  }

  // Run on font-load (so glyph widths are right)
  function runAll() {
    document.querySelectorAll('.flip').forEach(el => play(el));
  }
  if (document.fonts && document.fonts.ready) {
    document.fonts.ready.then(() => setTimeout(runAll, 250));
  } else {
    setTimeout(runAll, 600);
  }

  // Click to replay
  document.addEventListener('click', e => {
    const el = e.target.closest('.flip');
    if (el && !el.classList.contains('flipping')) play(el);
  });
})();

4. Parameters you can tweak

ConstantDefaultEffect
POOL A–Z 0–9 #@%&*+=°/ Which random glyphs flash before locking. Add emoji for chaos.
STEP 55 ms How fast each letter cycles. Lower = faster spin.
PER_LETTER 9 Random glyphs shown per letter before locking. Higher = longer animation.
STAGGER 70 ms Delay between letters starting. Higher = wavier reveal.

Total duration ≈ (N_chars × STAGGER) + (PER_LETTER × STEP) + 400. For 14 chars: ~1900 ms.

5. Variants

Same logic, different palette. Click any to play.

LIME
neon-lime (default)
CYAN
neon-cyan
PINK
neon-pink
GOLD
neon-yellow
Liked this? Feed Mr. Knife & Ms. Ling.
And buy their owner a milk tea.
🧋 TREAT THE SWAMP
Want more components? 5 more in the garden: Pond Ripple, Firefly Tour, Cat Wanderer, Xylophone Lights, Swamp Name Generator.
Browse all →