Skip to content

Scramble Decode

A copy-paste text effects component in pure HTML, CSS & vanilla JS. Zero dependencies, framework-agnostic, MIT-licensed.

Text EffectsHTMLCSSJavaScriptany framework
DECODE

Copy into your project

HTML
<!-- Scramble Decode — text decodes from random chars (vanilla JS) -->
<span class="nuda-scramble-decode" data-nuda-decode="DECODE">DECODE</span>
CSS
/* ── Scramble Decode ─────────────────────────────────────────
   JS-driven decode reveal; CSS handles the base styling.
   Customize:
     --nuda-sd-clr   : text color
     --nuda-sd-size  : font size
   ──────────────────────────────────────────────────────────── */
.nuda-scramble-decode {
  --nuda-sd-clr: #e4ff54;
  --nuda-sd-size: 1.8rem;

  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--nuda-sd-size);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--nuda-sd-clr);
  display: inline-block;
  text-shadow: 0 0 18px rgba(228, 255, 84, 0.35);
}
JavaScript
/* ── Scramble Decode — vanilla JS ────────────────────────────
   Each character scrambles through random glyphs, locking in
   left-to-right until the final word is revealed.
   Respects prefers-reduced-motion.
   ──────────────────────────────────────────────────────────── */
;(function () {
  var reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  var glyphs = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#%&*";

  document.querySelectorAll("[data-nuda-decode]").forEach(function (el) {
    var finalText = el.getAttribute("data-nuda-decode") || el.textContent;

    if (reduce) {
      el.textContent = finalText;
      return;
    }

    var frame = 0;
    var perChar = 3; /* frames before a char locks */
    var timer = setInterval(function () {
      var locked = Math.floor(frame / perChar);
      el.textContent = finalText
        .split("")
        .map(function (ch, i) {
          if (i < locked || ch === " ") return finalText[i];
          return glyphs[Math.floor(Math.random() * glyphs.length)];
        })
        .join("");
      frame++;
      if (locked >= finalText.length) clearInterval(timer);
    }, 45);
  });
})();

How to use Scramble Decode

Paste the HTML where you need it and the CSS into a global stylesheet (or a <style> tag). Every class is prefixed nuda- so it never collides with Tailwind or your own styles. Tweak the CSS custom properties to match your design system.

Works in React, Vue, Svelte, Astro, Next.js, Nuxt, Laravel Blade, Django, Rails — or a single .html file. No npm install, no build step.

More text effects components

← Browse all NudaUI components