Blog / CSS

Glitch and Distortion Effects: RGB Split and VHS

Learn to create glitch, RGB split, VHS scanlines and CRT effects in pure CSS. Retro-futuristic techniques to give your interfaces a unique cyberpunk style.

Introduction

Glitch and distortion effects bring a cyberpunk and retro-futuristic aesthetic to your web interfaces. Inspired by the visual artifacts of old VHS cassettes, CRT screens and digital errors, these effects have become an essential element of modern design.

In this tutorial, we will explore 5 different techniques to create distortion effects in pure CSS: classic glitch text, RGB split (chromatic aberration), VHS scanlines, CRT screen and static noise. Each technique is accompanied by complete code and an interactive demo.

💡
Good to know

These effects primarily use ::before and ::after pseudo-elements, clip-path and @keyframes. They are compatible with all modern browsers without prefixes.

1. Glitch Text Effect

The classic glitch effect consists of duplicating the text via pseudo-elements, then moving each copy asynchronously with a color offset. The result evokes a very recognizable digital display error.

The technique relies on three overlapping text layers: the original text, a magenta copy (::before) cropped on the top half, and a cyan copy (::after) on the bottom half. Both copies are animated independently.

GLITCH
glitch-text.css
.glitch {
  position: relative;
  font-size: 4rem;
  font-weight: 900;
  color: white;
  letter-spacing: 4px;
}

/* Text duplication with pseudo-elements */
.glitch::before,
.glitch::after {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

/* Magenta layer - top half */
.glitch::before {
  color: #ff00ff;
  animation: glitchTop 2s infinite linear alternate-reverse;
  clip-path: polygon(0 0, 100% 0, 100% 45%, 0 45%);
}

/* Cyan layer - bottom half */
.glitch::after {
  color: #00ffff;
  animation: glitchBottom 3s infinite linear alternate-reverse;
  clip-path: polygon(0 55%, 100% 55%, 100% 100%, 0 100%);
}

@keyframes glitchTop {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-3px); }
  40% { transform: translateX(3px); }
  60% { transform: translateX(-2px); }
  80% { transform: translateX(2px); }
}

@keyframes glitchBottom {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(2px); }
  50% { transform: translateX(-3px); }
  75% { transform: translateX(1px); }
}

How it works

The principle relies on three overlapping layers:

  • content: attr(data-text): Duplicates the original text in pseudo-elements without repeating it in the HTML
  • clip-path: polygon(): Crops each pseudo-element to show only a portion of the text
  • Two desynchronized animations: The layers move at different speeds and directions for a random effect

2. RGB Split Effect

RGB split, also called chromatic aberration, simulates the separation of red, green and blue color channels. It is an artifact found on damaged photographic lenses and failing screens.

Unlike the classic glitch, RGB split focuses on color offset rather than erratic movement. The result is more subtle but equally impactful.

RGB SPLIT
rgb-split.css
.rgb-split {
  position: relative;
  font-size: 3rem;
  font-weight: 900;
  letter-spacing: 3px;
}

/* Canal rouge - tiers superieur */
.rgb-split::before {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: -2px;
  text-shadow: 2px 0 #ff0000;
  animation: rgbShift 0.5s infinite alternate;
  clip-path: polygon(0 0, 100% 0, 100% 33%, 0 33%);
}

/* Canal cyan - tiers inferieur */
.rgb-split::after {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 2px;
  text-shadow: -2px 0 #00ffff;
  animation: rgbShift 0.5s infinite alternate-reverse;
  clip-path: polygon(0 66%, 100% 66%, 100% 100%, 0 100%);
}

@keyframes rgbShift {
  to {
    transform: translateX(3px);
  }
}
⚠️
Readability warning

RGB split can make text difficult to read if the offset is too large. Keep translateX values below 5px and reserve this effect for headings or decorative elements, never for main text content.

3. VHS / Scanlines

The VHS effect reproduces the appearance of analog video cassettes with their horizontal scan lines (scanlines) and subtle flickering. It is a classic of the retrowave and synthwave aesthetic.

The technique uses a repeating-linear-gradient to create scan lines and a second pseudo-element to simulate the flickering of the magnetic tape.

VHS EFFECT
vhs-scanlines.css
.vhs-container {
  position: relative;
  padding: 40px;
  background: #111;
  overflow: hidden;
}

/* Scanlines - horizontal lines */
.vhs-container::before {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    0deg,
    transparent,
    transparent 2px,
    rgba(0,0,0,0.3) 2px,
    rgba(0,0,0,0.3) 4px
  );
  pointer-events: none;
  animation: scanlines 0.1s infinite linear;
}

/* Band flickering */
.vhs-container::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255,255,255,0.03) 50%,
    transparent 100%
  );
  animation: vhsFlicker 0.15s infinite;
}

@keyframes scanlines {
  0% { transform: translateY(0); }
  100% { transform: translateY(4px); }
}

@keyframes vhsFlicker {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.98; }
}

Customizing the scanlines

You can adjust several parameters to achieve the desired effect:

  • Line thickness: Modify the 2px and 4px values in the gradient. Wider lines give a more retro look
  • Opacity: Adjust the 0.3 in rgba(0,0,0,0.3) for more or less visible lines
  • Scan speed: Change the animation duration (0.1s) for faster or slower scrolling

4. CRT Screen Effect

The CRT (Cathode Ray Tube) screen is a classic of retro design. It combines radial vignetting, fine scanlines and green phosphorescent text to evoke the computer terminals of the 80s.

This effect is particularly effective for the "terminal" sections of your sites, status pages or any element that needs to evoke vintage technology.

> SYSTEM READY_
> Loading effects.css...
> Done.
crt-screen.css
.crt {
  position: relative;
  padding: 40px 60px;
  background: #000;
  border-radius: 20px;
  overflow: hidden;
}

/* Vignettage radial */
.crt::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse at center,
    transparent 0%,
    rgba(0,0,0,0.4) 100%
  );
  pointer-events: none;
}

/* Fine CRT scanlines */
.crt::after {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    0deg,
    transparent,
    transparent 1px,
    rgba(0,0,0,0.15) 1px,
    rgba(0,0,0,0.15) 2px
  );
  pointer-events: none;
}

/* Texte phosphorescent */
.crt-text {
  font-family: 'JetBrains Mono', monospace;
  color: #00ff00;
  text-shadow:
    0 0 5px #00ff00,
    0 0 10px #00ff00;
  animation: crtFlicker 0.05s infinite;
}

@keyframes crtFlicker {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.98; }
}
💡
Amber variant

Replace #00ff00 with #ffb000 for an amber CRT screen, typical of IBM monitors from the 80s. You can also use #33ff33 for a brighter Apple II-style green.

5. Noise / Static Overlay

Static noise adds an animated grainy texture over your elements. It simulates the background noise of analog signals and perfectly complements the other retro effects.

The trick is to use an inline SVG with a feTurbulence filter encoded as a data URI. This is a performant method that requires no external image file.

NOISE EFFECT
noise-overlay.css
.noise-overlay {
  position: relative;
  overflow: hidden;
}

.noise-overlay::after {
  content: '';
  position: absolute;
  inset: 0;

  /* Inline SVG with feTurbulence filter */
  background-image: url("data:image/svg+xml,%3Csvg
    viewBox='0 0 400 400'
    xmlns='http://www.w3.org/2000/svg'%3E
    %3Cfilter id='n'%3E
      %3CfeTurbulence type='fractalNoise'
        baseFrequency='0.9'
        numOctaves='3'
        stitchTiles='stitch'/%3E
    %3C/filter%3E
    %3Crect width='100%25' height='100%25'
      filter='url(%23n)'/%3E
  %3C/svg%3E");

  opacity: 0.15;
  pointer-events: none;
  animation: noiseAnim 0.2s infinite;
}

@keyframes noiseAnim {
  0%, 100% {
    transform: translate(0, 0);
  }
  25% {
    transform: translate(-1%, 1%);
  }
  50% {
    transform: translate(1%, -1%);
  }
  75% {
    transform: translate(-1%, -1%);
  }
}
🎨
Combining effects

The noise overlay combines perfectly with VHS and CRT effects. Apply it on the same container as the scanlines for an even more authentic result. Adjust the opacity between 0.05 and 0.2 depending on the desired intensity.

Best practices

Before concluding, here are some recommendations for using glitch and distortion effects effectively:

Performance

  • Limit simultaneous animations: each animated pseudo-element consumes GPU resources. Avoid having more than 2-3 active effects at once
  • Use will-change: transform on animated elements to enable hardware acceleration
  • Prefer transform over left/top: transformations are composited on the GPU, unlike positioning properties
  • Disable off-viewport animations with the Intersection Observer to save resources

Design

  • Reserve glitches for headings: main text content must remain readable
  • Dark background mandatory: glitch and CRT effects only work visually on black or very dark backgrounds
  • Dose the intensity: a 2-3px offset is sufficient. Beyond that, the effect becomes unpleasant
  • Universe consistency: combine these effects together for a coherent retro theme

Accessibility

accessibility.css
/* Disable animations for sensitive users */
@media (prefers-reduced-motion: reduce) {
  .glitch::before,
  .glitch::after,
  .rgb-split::before,
  .rgb-split::after,
  .vhs-container::before,
  .vhs-container::after,
  .crt-text,
  .noise-overlay::after {
    animation: none;
  }

  /* Hide decorative pseudo-elements */
  .glitch::before,
  .glitch::after {
    display: none;
  }
}
⚠️
Epilepsy and photosensitivity

Fast flickering effects can trigger seizures in people with epilepsy. Always use @media (prefers-reduced-motion: reduce) and avoid flashing frequencies between 3 and 60 Hz.

Conclusion

Glitch and distortion effects are powerful tools for creating a unique retro-futuristic aesthetic. By combining pseudo-elements, clip-path, @keyframes and SVG filters, you can reproduce all analog visual artifacts in pure CSS.

Remember that these effects are primarily decorative. Use them sparingly, on non-essential elements, and always think about accessibility. CSS keeps evolving and offers creative possibilities without resorting to JavaScript!

🎨
Go further

Find over 30 visual effects ready to use in our effects library, including glitch, neon and cyberpunk variants with one-click copyable code.