VHS

Glitch & Distortion · Animated · pure CSS

VHS chroma-bleed: offset color copies, vertical jitter and scanlines for that worn-tape look. Lo-fi nostalgia for titles.

VHS

CSS

/* VHS — generated with TEXT-FX
 * HTML: the element needs a data-text attribute equal to its text.
 * Font: 'Syne', sans-serif (load from Google Fonts).
 */

.text-effect {
  font-family: 'Syne', sans-serif;
  font-weight: 700;
  letter-spacing: 4px;
  text-transform: none;
}

.text-effect {
  position: relative;
  background: repeating-linear-gradient(0deg, #ededed 0px, #ededed 3px, hsl(0 0% 62%) 3px, hsl(0 0% 62%) 4px);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  background-size: 100% 7px;
  filter: drop-shadow(0 0 2px hsl(190 90% 60% / 0.5)) drop-shadow(0 0 6px hsl(190 90% 60% / 0.5));
  animation:
    text-effect-jitter 0.38s steps(2, end) infinite,
    text-effect-scan 3.0s linear infinite;
}
.text-effect::before,
.text-effect::after {
  content: attr(data-text);
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: 0.85;
}
.text-effect::before {
  color: #ff3b30;
  transform: translate(-2.7px, 0);
  animation: text-effect-bleedR 2.49s ease-in-out infinite;
}
.text-effect::after {
  color: #2f9bff;
  transform: translate(2.7px, 0);
  animation: text-effect-bleedB 3.0s ease-in-out infinite;
}

@keyframes text-effect-jitter {
  0%   { transform: translateY(0); }
  50%  { transform: translateY(1.35px); }
  100% { transform: translateY(0); }
}
@keyframes text-effect-scan {
  0%   { background-position: 0 0; }
  100% { background-position: 0 7px; }
}
@keyframes text-effect-bleedR {
  0%, 100% { transform: translate(-2.7px, 0); }
  45%      { transform: translate(-4.32px, 1.08px); }
  70%      { transform: translate(-1.35px, -0.81px); }
}
@keyframes text-effect-bleedB {
  0%, 100% { transform: translate(2.7px, 0); }
  40%      { transform: translate(4.32px, -1.08px); }
  75%      { transform: translate(1.35px, 0.81px); }
}

HTML

This effect needs the markup below (per-letter spans, SVG defs, or a data-text attribute).

<style>
.text-effect {
  font-family: 'Syne', sans-serif;
  font-weight: 700;
  letter-spacing: 4px;
  text-transform: none;
}

.text-effect {
  position: relative;
  background: repeating-linear-gradient(0deg, #ededed 0px, #ededed 3px, hsl(0 0% 62%) 3px, hsl(0 0% 62%) 4px);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  background-size: 100% 7px;
  filter: drop-shadow(0 0 2px hsl(190 90% 60% / 0.5)) drop-shadow(0 0 6px hsl(190 90% 60% / 0.5));
  animation:
    text-effect-jitter 0.38s steps(2, end) infinite,
    text-effect-scan 3.0s linear infinite;
}
.text-effect::before,
.text-effect::after {
  content: attr(data-text);
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: 0.85;
}
.text-effect::before {
  color: #ff3b30;
  transform: translate(-2.7px, 0);
  animation: text-effect-bleedR 2.49s ease-in-out infinite;
}
.text-effect::after {
  color: #2f9bff;
  transform: translate(2.7px, 0);
  animation: text-effect-bleedB 3.0s ease-in-out infinite;
}

@keyframes text-effect-jitter {
  0%   { transform: translateY(0); }
  50%  { transform: translateY(1.35px); }
  100% { transform: translateY(0); }
}
@keyframes text-effect-scan {
  0%   { background-position: 0 0; }
  100% { background-position: 0 7px; }
}
@keyframes text-effect-bleedR {
  0%, 100% { transform: translate(-2.7px, 0); }
  45%      { transform: translate(-4.32px, 1.08px); }
  70%      { transform: translate(-1.35px, -0.81px); }
}
@keyframes text-effect-bleedB {
  0%, 100% { transform: translate(2.7px, 0); }
  40%      { transform: translate(4.32px, -1.08px); }
  75%      { transform: translate(1.35px, 0.81px); }
}
</style>

<div data-text="Your text" class="text-effect">Your text</div>
Category
Glitch & Distortion
Type
Animated
Browser support
background-clip:text scanlines + pseudo-element chroma copies
Capabilities
dataText

Related Glitch & Distortion effects