Glitching the DOM
I wanted a glitch effect for one of my website. Ended up writing a library. Here’s how it works.
::before and ::after seemed obvious. Clip a slice, shift it sideways. Works for simple text, but try it on an image or anything with its own layout and it falls apart. You can’t escape the stacking context you’re in.
The fix: clone the element, animate the clone, don’t touch the original.
Wrap it in two containers, clone it inside the inner one, stack everything with CSS grid. display: grid + grid-area: 1/1/-1/-1 on every child puts them all in the same cell. No absolute positioning, page layout untouched. cloneNode(true) means images, SVGs, buttons — anything — just works.
hover to glitch
Each clone shows a random horizontal band via clip-path: polygon(), shifted sideways with translate3d. hue-rotate handles the color shift. The key to making it look digital: steps(N, jump-start) as the easing. No interpolation, ever. Hard cuts, like a corrupted signal.
20 slices, high velocity
Constant glitching looks cheap. The real effect has a rhythm. glitchTimeSpan defines a window in the loop where intensity peaks — outside it, layers are hidden, at the center it’s full chaos, triangle curve in between.
glitchTimeSpan: false
glitchTimeSpan: { start: 0.5, end: 0.7 }
Play modes: always, hover, click, manual. All just wrappers around element.animate() and animation.cancel().
playMode: always
playMode: hover
playMode: click
Under 2 kB gzipped, no dependencies, GPU-accelerated, works on anything.
import { PowerGlitch } from "powerglitch";
PowerGlitch.glitch(".my-element", {
playMode: "hover",
timing: { duration: 2000, iterations: Infinity },
glitchTimeSpan: { start: 0.5, end: 0.7 },
slice: { count: 6, velocity: 15, hueRotate: true },
shake: { velocity: 15, amplitudeX: 0.2, amplitudeY: 0.2 },
});
hover — full options
There’s a playground if you want to mess with the params.