Text Scramble
On hover, all letters simultaneously switch to random characters then reveal left to right during the hover, 30 ms per step.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Hover has 48 effects, including 5 free. Explore the category →
3 usage examples



How it works
The .fx-0373-root frame holds a .tsx-text element with a data-text attribute containing the final text. On load, the script reads that attribute and assigns it as aria-label so screen readers always announce the final text, regardless of the visual state. The element gets tabindex="0" role="text" to be keyboard-focusable.
On mouseenter (or focus), the disintegration animation starts: each letter is randomly replaced by a character from the alphanumeric pool (36 characters: A-Z and 0-9) every 30 ms. The reinstallation animation starts on mouseleave (or blur): correct letters are restored left to right, one by one, at the same 30 ms pace. Hovering again during reinstallation interrupts it.
Under prefers-reduced-motion: reduce, the text instantly shows its final state with no intermediate animation: on hover, it jumps directly to the value in data-text. Enter and Space trigger the same scramble as hover/click, for keyboard accessibility.
Accessibility
- Screen readers: the visible text (
.tsx-visual) carriesaria-hidden="true"; a visually hidden element (.tsx-sr) permanently holds the final text. Screen readers always read this real text — scrambled characters are never announced. - Keyboard: the element is focusable by Tab (
tabindex="0").focusandblurevents trigger the same animations asmouseenterandmouseleave. Enter and Space can also trigger the scramble. - Reduced motion: under
prefers-reduced-motion: reduce, no intermediate animation occurs; the final text is shown directly on hover and stays on mouse-out. Zero animated letter changes. - Semantics: the
.tsx-textelement is a focusable<div>with no extra ARIA role. If the effect is applied to a heading or a link, keep the native HTML semantics (<h2>,<a>) and apply the JS on top of it.
Browser compatibility
JS + CSS, under 1.5 KB, no dependency. Animations are driven by setInterval at 30 ms. Compatible with all modern browsers. Measured in Chromium 151, Firefox 153 and WebKit 26: disintegration and reinstallation identical in all three. The effect does not use requestAnimationFrame: the 30 ms pace is constant regardless of display frequency.
Without JavaScript, the .tsx-text element shows its text as-is, without animation. On mobile without hover, the effect fires on focus (tap on the element); it remains visible as long as the element is focused.
The code
HTML structure to paste into your page (the CSS + JS come with your purchase):
<div class="fx-0373-root">
<div class="tsx-text" data-text="Your text" tabindex="0">Your text</div>
</div>
One-time payment, no subscription — the code is yours forever
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Displayed text (HTML — data-text attribute) |
"HOVER ME" | Replace with any text. The initial visible content can be the same (HOVER ME) or different — the scramble always shows the value of data-text as the final state. |
Animation speed (JS — 30 ms per step) |
30 ms per step | Lower to 20 ms for a fast, snappy look; raise to 60 ms for a slow, contemplative decode. |
Character pool (JS — chars array) |
A-Z and 0-9 (36 characters) | Replace with symbols (!@#$%^&*) for a more esoteric look, digits only (0-9) for a numeric look, or characters from another language. |
Font (CSS — font-family on .tsx-text) |
inherited from document | A monospace font (Courier New, JetBrains Mono) is recommended: fixed-width characters prevent the text from vibrating laterally during scramble. |
| Trigger (JS — events) | mouseenter / mouseleave + focus / blur |
To trigger on click instead of hover, replace the listeners with click. For an automatic animation on load, call the disintegration function without an event. |
FAQ
.fx-0373-root frames as needed; each instance is isolated by document.querySelectorAll. Each has its own data-text, its own interval and its own animation..tsx-text) and in the aria-label; search engines read it normally. Make sure the data-text value and the initial content are identical to avoid any confusion.