GLITCH LAB v1.0 ezolab.dev / lab instrument SYS: READY

Effects/ Chromatic Wave [FX_01]/ Calibrated

Chromatic Wave

#animation#rgb#text Light · zero deps

Letters roll like a wave while their colour channels drift apart. Pure CSS + 6 lines of JS.

Live viewport Optical bench
LIVE FEED 60.0 FPS | FRAME: 16.7ms RES: — [ + calibrated ]
Kind: CSS + JS   Weight: Light Test bench status: operational

Parameter calibration [inspector]

Active chromatic channels

↻ Auto-synced to CSS

How it works // breakdown

Spec-FX_01

Every letter of the word lives in its own span. That is the only job of the JavaScript: it splits the text and tells each letter its position.

The colour split is pure CSS. text-shadow draws two coloured copies of each letter — lime to the left, red to the right — which looks like a TV losing its colour channels.

The wave comes from one keyframe that moves a letter down and back. Each letter starts a little later than the previous one (its index times --gw-delay), so the motion rolls through the word instead of moving it as one block.

All settings are CSS variables at the top of the CSS. Change them by hand or in the playground above, then copy the result.

.zip
.gw-wave {
  --gw-shift: 6px;
  --gw-height: 12px;
  --gw-speed: 1.2s;
  --gw-delay: 80ms;
  --gw-left: #d4ff00;
  --gw-right: #ff3131;
  font: 700 clamp(48px, 12vw, 120px)/1 system-ui, sans-serif;
  color: #f3f4f6;
  letter-spacing: .02em;
}
.gw-wave span {
  display: inline-block;
  animation: gw-wave var(--gw-speed) ease-in-out infinite;
  animation-delay: calc(var(--gw-i) * var(--gw-delay));
  text-shadow:
    calc(var(--gw-shift) * -1) 0 var(--gw-left),
    var(--gw-shift) 0 var(--gw-right);
}
@keyframes gw-wave {
  50% { transform: translateY(var(--gw-height)); }
}
@media (prefers-reduced-motion: reduce) {
  .gw-wave span { animation: none; }
}