← All Examples

Glitch Effect

An animated glitch effect using CSS clip-path, pseudo-elements, and keyframes — no JavaScript.

Published May 19, 2026

Demo

Glitch
Glitch

HTML

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

CSS

.glitch {
  position: relative;
  font-size: 3rem;
  font-weight: 800;
  letter-spacing: .05em;
  color: #f0f0f0;
}

.glitch::before,
.glitch::after {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.glitch::before {
  color: #57d9a3;
  animation: glitch-1 2.5s infinite;
}

.glitch::after {
  color: #ff6b6b;
  animation: glitch-2 2.5s infinite;
}

@keyframes glitch-1 {
  0%, 90%, 100% { clip-path: inset(0 0 100% 0); left: 0; }
  92%  { clip-path: inset(20% 0 60% 0); left: -3px; }
  94%  { clip-path: inset(50% 0 30% 0); left:  2px; }
  96%  { clip-path: inset(10% 0 75% 0); left: -2px; }
  98%  { clip-path: inset(65% 0 10% 0); left:  3px; }
}

@keyframes glitch-2 {
  0%, 88%, 100% { clip-path: inset(0 0 100% 0); left: 0; }
  90%  { clip-path: inset(40% 0 40% 0); left:  3px; }
  92%  { clip-path: inset(5%  0 80% 0); left: -3px; }
  94%  { clip-path: inset(75% 0 5%  0); left:  2px; }
  96%  { clip-path: inset(30% 0 55% 0); left: -2px; }

How it works

Two ::before and ::after pseudo-elements clone the text using content: attr(data-text). Each clone is offset horizontally with left and colored using color. Rapidly switching clip-path: inset() slices inside @keyframes creates the scan-line tearing. The parent uses position:relative to contain the pseudo-elements.