CSS Glitch Effect — Tutorial & Generator

Learn how to create a glitch effect with pure CSS, on text, images, buttons and more. Customize and copy the code.

Create a Glitch Effect with CSS

Hover over the preview to trigger the glitch. Adjust intensity, speed, and color channels below, then copy the generated CSS.

GLITCH
How the text glitch works ↓
1px4px20px
0.1s0.3s0.8s

HTML: <span class="glitch" data-text="GLITCH">GLITCH</span>

Text Glitch Effect

Distort headings and text with clip-path slicing and color-shifted pseudo-elements

See This Effect as a Scroll Transition

The CSS version above works for hover and click interactions. But imagine this glitch effect playing between fullscreen sections as users scroll through your website: pixel-level distortion, chromatic aberration, and slice offsets all running on the GPU at 60 fps.

Scroll inside the preview below to see the WebGL glitch transition in action. Adjust the speed to find the right feel:

Loading preview...

fullPage.js adds

  • 80+ WebGL & CSS transitions
  • Touch & swipe support
  • Scroll snapping
  • Keyboard navigation
  • Anchor links & history
  • Lazy loading
  • 60fps GPU performance
Get fullPage.js →

Scroll inside the preview to see the glitch transition between sections

What Is a Glitch Effect?

A glitch effect is a visual technique that simulates digital or analog signal corruption, the kind of distortion you see when a screen malfunctions, a VHS tape degrades, or a data stream is interrupted. In web development, it refers to deliberately broken-looking animations applied to text, images, or entire sections to create a raw, edgy aesthetic.

Origin of the Glitch Aesthetic

The glitch aesthetic has its roots in glitch art, a movement that emerged in the late 1990s and early 2000s where artists intentionally corrupted digital files or manipulated hardware to produce unexpected visual artifacts. Inspired by CRT monitor failures, VHS tracking errors, and corrupted JPEG data, the style became a staple of cyberpunk, vaporwave, and electronic music culture. It eventually made its way into web design as CSS animations and blend modes became powerful enough to replicate the look natively in the browser.

What Elements Can It Be Applied To?

The CSS glitch effect is versatile and can be applied to virtually any HTML element:

When to Use a Glitch Effect

Glitch effects work best when the design calls for an unconventional, high-energy feel. Common use cases include:

Use the effect sparingly. A glitch animation on a single heading makes a strong statement, but applying it to every element on the page can quickly become overwhelming and hurt readability.

CSS Text Glitch Effect

The text glitch uses two pseudo-elements (::before and ::after) that duplicate the heading via content: attr(data-text). Each copy is tinted a different colour, cyan and magenta by default, to simulate RGB channel separation. The distortion comes from clip-path: inset(), which crops each pseudo-element to a thin horizontal strip, while transform: translate() shifts them off-axis:

.glitch::before,
.glitch::after {
  content: attr(data-text);
  position: absolute;
  top: 0; left: 0;
}
.glitch::before { color: #0ff; }
.glitch::after  { color: #f0f; }

@keyframes glitch-1 {
  0%  { clip-path: inset(20% 0 60% 0); transform: translate(4px, -2px); }
  50% { clip-path: inset(40% 0 30% 0); transform: translate(-4px, 2px); }
}

The key to making it feel authentically digital is steps(2) or steps(3) in the animation timing function. This removes easing entirely: each frame snaps to the next position, mimicking the way real signal corruption jumps rather than slides. Combine that with a short duration (0.2–0.4s) and infinite iteration for a continuous flicker, or restrict it to :hover to keep the page calm until the user interacts.

Browser support is excellent: clip-path: inset(), pseudo-elements, and @keyframes work in every modern browser. No JavaScript, no polyfills.

WebGL Glitch Effect

The WebGL approach runs the entire glitch pipeline on the GPU through a custom fragment shader. Two textures are loaded into a <canvas> element via WebGL, and the shader reads both during each frame. The image is divided into horizontal slices, each offset by a random amount, with a chromatic aberration pass that samples RGB channels at different UV coordinates:

// Fragment shader — slice offset + chromatic split
float slice = floor(uv.y * sliceCount);
float offset = random(slice + time) * maxOffset;
float r = texture2D(image, vec2(uv.x + offset + chromatic, uv.y)).r;
float g = texture2D(image, vec2(uv.x + offset, uv.y)).g;
float b = texture2D(image, vec2(uv.x + offset - chromatic, uv.y)).b;
gl_FragColor = vec4(r, g, b, 1.0);

Because everything is processed inside the GPU pipeline, there is no DOM manipulation and no reflow. The animation loop uses requestAnimationFrame and updates a single uniform float (the glitch progress) that the shader interpolates. This makes it trivially smooth even at high slice counts.

The trade-off vs pure CSS: WebGL requires images served from the same origin or a CORS-enabled CDN, since the shader reads raw pixel data via texImage2D. The result, however, is far more flexible: you get real per-pixel displacement, not just clipped layers.

CSS Image Glitch Effect

The image glitch applies the same pseudo-element strategy as text, but adapted for raster content. The container inherits its background to both ::before and ::after, each tinted with mix-blend-mode: multiply to produce colour-shifted copies:

.glitch-img::before,
.glitch-img::after {
  content: '';
  position: absolute;
  inset: 0;
  background: inherit;
  background-size: cover;
  mix-blend-mode: multiply;
}
.glitch-img::before { background-color: #0ff; }
.glitch-img::after  { background-color: #f0f; }

.glitch-img:hover::before {
  animation: glitch-img 0.3s infinite steps(3);
}

On hover, both pseudo-elements animate using clip-path: inset() to show only a horizontal slice at a time, while transform: translateX() offsets them in opposite directions. The steps(3) timing gives it a jumpy, corrupted-signal feel. The original image stays solid underneath; only the coloured layers shift.

The presets in the generator above change the number of visible slices, the blend mode, and the offset range. "Scanline" uses narrow insets for thin strips; "Heavy" uses wider insets and larger translations; "Neon" swaps the tints for bright contrasting colours.

CSS Scanline Glitch Effect

The scanline technique stacks multiple copies of the same background image, five layers by default, inside a single container. Each layer is a <div> positioned absolutely to fill the parent, oversized by a gap value to create thin transparent scanlines:

.scanline__img {
  position: absolute;
  top: calc(-1 * var(--gap-v));
  left: calc(-1 * var(--gap-h));
  width: calc(100% + var(--gap-h) * 2);
  height: calc(100% + var(--gap-v) * 2);
  background: url('photo.jpg') no-repeat center / cover;
}
.scanline__img:nth-child(2) {
  background-color: #f3727e;
  background-blend-mode: color-dodge;
}

Each layer is animated with a different @keyframes sequence that changes transform: translate() and clip-path at staggered intervals. Layers 2+ are tinted with background-blend-mode (colour-dodge, luminosity, etc.) to create colour interference between them. The result looks like a broken interlaced signal: horizontal bands of colour drifting at different speeds.

The direction control switches between horizontal and vertical scanlines by rotating the background-size axis and the translate direction. Blend mode and colour controls per layer give fine-grained control over the interference pattern.

CSS Color Shift Glitch Effect

The colour shift (chromatic aberration) effect creates a pseudo-element copy of an image with mix-blend-mode: hard-light, then jitters its position through a keyframe sequence. Because the layer is offset by only a few pixels, the visual result is a subtle colour fringe around every edge, the same artifact real camera lenses produce at wide apertures:

.color-shift::before {
  content: '';
  position: absolute;
  inset: 0;
  background: inherit;
  opacity: .5;
  mix-blend-mode: hard-light;
}
@keyframes color-shift {
  0%  { background-position: 0 0;    filter: hue-rotate(0deg); }
  30% { background-position: 15px 0; }
  60% { background-position: -50px 0; }
  100%{ background-position: 0 0;    filter: hue-rotate(360deg); }
}

At low intensity (1–3px) the effect looks like a lens defect; at high intensity (10–20px) it becomes a full chromatic split. The steps() timing function makes the movement snap rather than slide.

This is the most versatile variant for production use: it works well as a subtle hover state on cards or hero images without overwhelming the design.

CSS RGB Split Glitch Effect

The RGB split takes a literal approach: three copies of the same image are stacked inside a container, each filtered by an SVG <feColorMatrix> to isolate a single colour channel. The three layers are composited with mix-blend-mode: screen, which is additive, so R + G + B reconstructs the original colour:

<!-- SVG filters to isolate each channel -->
<filter id="red">
  <feColorMatrix values="1 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 1 0"/>
</filter>
<filter id="green">
  <feColorMatrix values="0 0 0 0 0  0 1 0 0 0  0 0 0 0 0  0 0 0 1 0"/>
</filter>

<!-- CSS -->
.rgb-red   { filter: url(#red);   mix-blend-mode: screen; }
.rgb-green { filter: url(#green); mix-blend-mode: screen; }
.rgb-blue  { filter: url(#blue);  mix-blend-mode: screen; }

On hover, each channel is animated to translate a few pixels in a different direction. Because the layers are additively blended, the offset creates true anaglyph-style colour separation: reds shift left, blues shift right, and green stays centred (or vice versa). The effect is identical to what you see through misaligned 3D glasses.

Unlike the pseudo-element approaches, this method gives you independent control over each colour channel. The trade-off is three <img> elements in the DOM instead of CSS-only pseudo-elements, plus the inline SVG filter definitions.

CSS Button Glitch Effect

The button glitch positions two pseudo-elements behind the button using z-index: -1. Each is a full copy of the button's dimensions, tinted cyan and magenta. In the resting state, both sit exactly behind the button and are invisible:

.glitch-btn::before,
.glitch-btn::after {
  content: '';
  position: absolute;
  inset: 0;
}
.glitch-btn::before { background: #0ff; z-index: -1; }
.glitch-btn::after  { background: #f0f; z-index: -2; }

.glitch-btn:hover::before {
  animation: btn-jitter 0.3s ease 0.1s infinite;
}
.glitch-btn:hover::after {
  animation: btn-jitter 0.3s ease infinite reverse;
}

On :hover, both pseudo-elements animate with transform: translate(), creating coloured slices that jitter around the edges of the button. The inner text stays solid and readable; only the coloured "echoes" move. The steps(2) timing function makes the movement instant and digital rather than smooth.

For best results, use a solid background colour on the button so the pseudo-element tints contrast sharply. The effect works on any clickable element: <button>, <a>, or any block with position: relative.

Glitch Effect Design Tips

A well-tuned glitch effect feels intentional and polished. A poorly tuned one feels broken. Here are some practical guidelines to get it right.

Keep it subtle by default

Small offsets (2-4 px) and short durations (0.2-0.4 s) feel dynamic without being distracting. Reserve high-intensity glitches for hover or transition moments.

Use steps() for authenticity

Smooth easing looks wrong on a glitch. Real signal corruption is instant. Use steps(2) or steps(3) in your animation timing for that digital snap.

Limit to one focal element

Glitching everything on the page creates visual noise. Apply it to one headline, one hero image, or one CTA button. Let the rest of the page breathe.

Choose your colour channels

Cyan + magenta is the classic RGB split, but you can use brand colours instead. Keep the two tints complementary for the best contrast.

Respect reduced motion

Wrap your glitch animations inside @media (prefers-reduced-motion: no-preference) so users who find motion uncomfortable see a static version.

Combine techniques

Layer clip-path slicing with a text-shadow RGB split or add a subtle skew transform. Mixing two lightweight effects often looks richer than cranking one to the max.

Where Glitch Effects Look Great

Creative portfolios

Glitch effects add personality to designer and developer portfolio sites, especially for digital art, gaming, or cyberpunk aesthetics.

Error & 404 pages

A glitch effect on the error message reinforces the "something went wrong" concept in a visually interesting way.

Product launches

Tech product reveals and startup landing pages use glitch transitions to convey innovation and cutting-edge technology.

Music & event pages

Concert pages, DJ portfolios, and music streaming interfaces use glitch aesthetics to match the energy of electronic music.

Video game websites

Game landing pages, esports team sites, and retro gaming blogs. Glitch effects fit naturally into the visual language of gaming culture.

Sci-fi & cyberpunk themes

Futuristic UI designs, hacker-themed pages, and dystopian storytelling sites use glitch as a core visual element of the world they're building.

FAQ

How do I make a glitch effect with CSS?
Use ::before and ::after pseudo-elements with clip-path: inset() to create horizontal slices, apply different colour tints (cyan and magenta) for RGB channel splitting, and animate with @keyframes using steps() for the jittery, digital look. See the interactive demo above to generate the code.
Can I use a CSS glitch effect on images?
Yes. Set the image as a background-image on the element and its pseudo-elements. Use mix-blend-mode: multiply with colour tints on the pseudo-elements, then animate with clip-path and transform offsets. The image demo tab above shows this technique.
How do I make a glitch effect on a button?
Use two pseudo-elements (::before with cyan and ::after with magenta) positioned behind the button, then animate them with a translate-based jitter on :hover. The inner content stays solid while the colour layers shift around it. See the "Button Glitch" tab in the generator above.
Does a CSS glitch effect hurt performance?
No. CSS animations on transform and clip-path are GPU-composited in modern browsers, so they don't trigger layout or paint. A single glitch effect has negligible performance cost. Avoid running dozens of glitch animations simultaneously on the same page.
How do I make the glitch effect accessible?
Wrap your glitch keyframes in a @media (prefers-reduced-motion: no-preference) query. Users who have enabled "Reduce motion" in their OS settings will see a static version. You can also limit the animation to :hover or :focus instead of running it continuously.
Can I change the glitch colours?
Yes. The classic look uses cyan (#0ff) and magenta (#f0f) because they mimic RGB channel separation, but you can use any two contrasting colours. For a subtler look, try two shades of the same hue with slight offsets.
How do I trigger the glitch on scroll instead of hover?
Use the Intersection Observer API to add a class (e.g., .glitch-active) when the element enters the viewport. Move your animation declarations to .glitch-active::before / .glitch-active::after so the effect only plays when visible.

Make Your Website Stand Out with Fullscreen Effects

Add scroll transitions, parallax and animations to your site with fullPage.js. One component, 80+ effects.

Brandire
New World of Work
OW Consulting

Powering fullscreen design for Google, Sony, BBC, eBay & more

Get fullPage.js
+ Suggest Effect