CSS Text Glitch Effect Generator
Type your text, tune the effect, and copy a self-contained glitch animation.
How It Works
Two extra copies of your text sit behind the original via ::before and ::after, each tinted a different neon color. A jumpy clip-path keyframe animation shifts those copies around fast enough to read as the classic RGB-split glitch.
Why the text appears twice in the markup
Look at the copied output and you'll notice the visible text string appears in two places: as the element's actual text content, and again inside a data-text="..." attribute. That's not redundant by accident, it's required. The ::before and ::after pseudo-elements can't read or duplicate an element's real rendered text content directly, CSS's content property has no way to say "copy whatever text is already inside this element." What it can do is read an HTML attribute's value with attr(data-text), so the data attribute exists purely to give the two pseudo-element copies something to pull their own text from. The practical implication: if you ever edit the visible text by hand after pasting this code, you must update the data-text attribute to match, or the glitch layers will silently keep showing stale text.
What clip-path: inset() is actually doing frame by frame
Each keyframe step uses clip-path: inset(top right bottom left) to reveal only a thin horizontal band of the colored duplicate layer while hiding the rest, then jumps to a different band on the next step. Combined with a small transform: translate() offset at each step, this creates the visual signature of a scanline briefly showing a mis-registered, offset copy of the text before snapping to a different slice, which is exactly the visual language of analog video signal corruption or a poorly synced CRT display that "glitch text" as a style is deliberately imitating.
Why the two color layers use different keyframe timing
The ::before layer's animation (glitch-1) steps through six keyframe stops at 0/20/40/60/80/100%, while the ::after layer's animation (glitch-2) uses only five stops at 0/25/50/75/100%, with different clip-path values at each point. Combined with the alternate-reverse animation direction, which plays the sequence forward then backward on alternating cycles, this deliberate mismatch keeps the two colored layers from ever landing in a synced, mirror-image position at the same moment. If both layers used identical timing, the effect would look far more mechanical and repetitive rather than chaotic.
An accessibility consideration worth adding yourself
A fast, flickering, high-contrast animation like this is exactly the category of motion that can be uncomfortable or genuinely triggering for users with vestibular disorders or photosensitive conditions, and the generated code here doesn't include any accommodation for that. Real-world use should wrap the animation in a @media (prefers-reduced-motion: reduce) query that sets animation: none on the ::before/::after layers, respecting the operating-system-level motion preference that users with these sensitivities have typically already switched on. This is a common gap in decorative CSS effects generally, not specific to this tool, but worth actively addressing before shipping any text-glitch effect to production.
Why the layers rely on position: absolute stacked over each other
The ::before and ::after pseudo-elements are both set to position: absolute; left: 0; top: 0; width: 100%; height: 100%, pinning them exactly on top of the original text rather than letting them flow normally in the document. Without that positioning, the two colored duplicate layers would simply stack vertically below the real text as separate lines, rather than overlapping it. The parent element needs position: relative (set on .glitch-text itself) for that absolute positioning to anchor correctly relative to the text's own box rather than drifting to the nearest positioned ancestor further up the page, which is why that property appears on the base class alongside the color and font-weight declarations.
Where this visual style comes from
The RGB-split look, where a shape or line of text appears to separate into misaligned red, green, or cyan-tinted copies, borrows its visual language from real analog video signal corruption: a damaged VHS tape, a poorly tuned CRT television, or a failing cable connection would genuinely misalign the red, green, and blue color channels of a broadcast signal. Digital design adopted this as an intentional aesthetic, especially in cyberpunk, retro-tech, and gaming-adjacent visual branding, precisely because the "malfunction" reads as recognizably digital-corrupted rather than simply blurry or low quality. Choosing complementary or high-contrast neon colors for the two layers (like this tool's default pink and cyan) leans further into that deliberate, stylized-glitch rather than realistic-error look.
Frequently Asked Questions
Why does my glitch text appear twice in the copied HTML?
CSS's content property can't copy an element's own rendered text directly into a ::before or ::after pseudo-element. The data-text attribute exists specifically so those pseudo-elements have something to read via attr(data-text). If you edit the visible text later, update the data-text attribute too, or the glitch layers will show outdated text.
What is clip-path: inset() doing in the keyframe animation?
It reveals only a thin horizontal band of each colored text layer at a time, jumping to a different band on each keyframe step. Combined with a small position offset, this recreates the look of a scanline briefly showing a misaligned duplicate of the text, mimicking analog signal corruption.
Why do the two colored layers use different numbers of keyframe steps?
Using different step counts and timing for each layer deliberately prevents them from ever landing in a perfectly synced, mirrored position at the same moment. Matching timing on both layers would make the effect look mechanical and repetitive rather than chaotic.
Should I add a reduced-motion fallback to this effect?
Yes, this is strongly recommended. Fast flickering, high-contrast animations can be uncomfortable or triggering for users with vestibular disorders or photosensitivity. Wrap the animation in an @media (prefers-reduced-motion: reduce) query that disables it for users who've enabled that OS-level accessibility preference.
Does this effect require any images or external assets?
No, it's entirely built from CSS pseudo-elements, clip-path, and keyframe animations applied to plain text. There's no image, font file, or JavaScript dependency beyond the copied HTML and CSS block.
Can I use more than two colors in the glitch effect?
Not with this generator's current structure, it's built around exactly two pseudo-element layers (::before and ::after), which is the maximum number of pseudo-elements a single element can have. A third color layer would require wrapping the text in an additional real HTML element.