webdevpuneet.com

Glitch Text — Free HTML CSS Cyberpunk Snippet

Glitch Text Effect · Animations · Plain HTML, CSS & JS · Live preview

CategoryAnimations

Copy & paste

Source Code

<div class="scene">
  <h1 class="glitch" data-text="GLITCH">GLITCH</h1>
  <p class="sub">CSS-only glitch effect using pseudo-elements and clip-path animation</p>
  <div class="btns">
    <button class="btn" onclick="setWord('GLITCH')">GLITCH</button>
    <button class="btn" onclick="setWord('ERROR')">ERROR</button>
    <button class="btn" onclick="setWord('SYSTEM')">SYSTEM</button>
    <button class="btn" onclick="setWord('BREACH')">BREACH</button>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

.glitch: :before/.after pseudo-elements display content: attr(data-text) — same text as element
Three layers: main element + two pseudo-elements, all absolutely positioned
clip-path: rect() slices each pseudo-element into different horizontal strips per keyframe
translateX and scaleX offsets on each layer mimic RGB channel separation
glitch-main animation on the base element adds coordinated shake
setWord(w) updates both textContent and dataset.text simultaneously
Monospace font + cyan colour + text-shadow for terminal/digital aesthetic
Export as HTML file, React JSX, or React + Tailwind CSS
Mobile (375px), Tablet (768px), Desktop device preview buttons
Live split-pane editor — preview updates as you type

About this UI Snippet

Glitch Text — ::before/::after Layered Copies, clip-path Slices & Channel Offset

Screenshot of the Glitch Text Effect snippet rendered live

The glitch text effect simulates digital signal corruption — the text appears to tear apart into colour-separated layers that momentarily misalign. Used on cyberpunk interfaces (pair it with matrix rain and neon glow buttons), gaming titles, error screens, and dark-themed products communicating disruption.

The effect uses three layers: the original .glitch element, .glitch::before, and .glitch::after. Both pseudo-elements display the same text via content: attr(data-text) — the same value set on the element in the HTML. All three layers are absolutely positioned on top of each other.

CSS @keyframes glitch-1 and glitch-2 apply different clip-path: rect() values to each pseudo-element at different frames, slicing each into horizontal strips. translateX() and scaleX() offsets separate the cyan (::before) and red (::after) colour channels, mimicking RGB misalignment in a corrupted video signal.

The setWord(w) JS function updates both element textContent and dataset.text simultaneously to keep the pseudo-element content in sync.

The CSS animation mechanics

Two ::before and ::after pseudo-elements are stacked on top of the base text using position: absolute; inset: 0. Each has content: attr(data-text) to display the same text. They use clip-path: rect(Npx, 9999px, Mpx, 0) to show only a horizontal slice of the text at a time — this creates the "torn apart lines" look. CSS keyframes shift the slices at different random offsets: transform: translate(-2px, 3px) and transform: translate(3px, -2px). The red and cyan colour shift uses text-shadow and mix-blend-mode: screen to simulate RGB channel separation.

The animation timing

The glitch animation runs in short bursts: steps() timing with very fast keyframes (0.08s total) creates a jerky, digital corruption feel rather than a smooth animation. Using animation-iteration-count: infinite with random-length pauses (via multiple steps in the keyframe) simulates the irregular nature of actual digital glitches.

Adding glitch to any element

The snippet uses data-text attribute to clone content into pseudo-elements — this is the only technique that works for CSS-only text duplication. Add data-text="Your text" to any element and apply the glitch CSS class. Dynamic text changes need the data-text attribute updated via JavaScript: el.dataset.text = el.textContent.

Triggering glitch on hover vs continuous

The snippet animates continuously by default. For a hover-only glitch, add animation-play-state: paused to the base state and animation-play-state: running on :hover. This triggers the glitch only when the user mouses over the text — a common pattern for interactive headings on portfolio sites.

Step by step

How to Use

  1. 1
    Watch the glitch animateThe text glitches continuously via CSS keyframes. Click the phrase buttons to swap to a different word and watch the glitch animate the new text.
  2. 2
    Update the wordsIn the HTML panel, change the button labels and the onclick setWord() arguments to your own phrases.
  3. 3
    Change the glitch coloursUpdate color on .glitch::before (cyan) and .glitch::after (red) in the CSS panel to any colour pair.
  4. 4
    Adjust glitch intensityIn the CSS keyframes, increase the translateX values and clip-path rect offsets for more aggressive glitching.
  5. 5
    Pause the animation on hoverAdd .glitch:hover { animation-play-state: paused } to freeze the glitch on hover.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component, or "Tailwind" for a React + Tailwind version.

Real-world uses

Common Use Cases

Cyberpunk and hacker aesthetic title screens
Glitch is the defining animation of cyberpunk, hacker, and sci-fi interfaces. Use on main title headings, loading screens, and error pages where the aesthetic communicates digital instability, corrupted data, or high-tech environments.
Error page and access denied headings
Apply to "404", "ERROR", or "ACCESS DENIED" headings on error pages. The glitch effect matches the failure theme semantically — corrupted text communicates a corrupted state, making the error feel intentional rather than accidental.
Learn CSS clip-path animation and channel separation
The effect layers three copies of the same text using content: attr(data-text). CSS keyframes slice each copy with clip-path: rect() and offset them with translateX to separate RGB colour channels. Edit each keyframe in the CSS panel to see how slicing and offsetting create the distortion.
Interactive word swap on button click
Wire the setWord() function to any trigger — a "Next" button cycles through phrases with a glitch transition between each one. The scramble effect provides a visual bridge between the old and new content.
Product name and brand reveals
Use for a dramatic product name reveal on a launch page. The text glitches for a moment before resolving into the actual name — creating a cinematic reveal that suggests the product has emerged from chaos.
Combine with text scramble for layered effects
Trigger the Text Scramble snippet first (characters decode to the word), then start the Glitch animation on the resolved text for a two-stage reveal: scramble → resolve → glitch → stable. The setWord() functions work together.
Related: Matter.js Confetti Cannon
See the Matter.js Confetti Cannon for a related animations pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

.glitch::before and .glitch::after are absolutely positioned on top of the original element. Both use content: attr(data-text) which reads the data-text HTML attribute — the same value as the element's textContent. All three layers overlap perfectly until the keyframe animations offset them.

CSS pseudo-elements cannot read their parent's textContent directly. data-text is an HTML attribute that mirrors the text, and content: attr(data-text) reads it. setWord(w) updates both el.textContent and el.dataset.text simultaneously to keep them in sync.

clip-path: rect(top, right, bottom, left) clips the element to a rectangle. Different rect() values in the keyframes create the horizontal slice effect — each pseudo-element shows only a specific band of the text at any given keyframe, creating the torn-apart appearance.

Remove the animation property from .glitch, .glitch::before, and .glitch::after. Add .glitch:hover, .glitch:hover::before, .glitch:hover::after { animation: ... }. The glitch fires only when hovered and stops when the cursor leaves.

In the keyframe percentages, make most of the animation frames have no transform applied: 0%,2%,4%,100% { ... } with only 1% and 3% having the glitch transforms. This makes the glitch occur only briefly at those percentages — 98% of the time the text is stable.

Yes. Manage the displayed word in useState. Set both the element text and data-text via React: <h1 className="glitch" data-text={word}>{word}</h1>. The CSS animations work without any React changes. To cycle words, use a setInterval that updates the word state.