SVG GLASS REFRACTION · ZERO DEPENDENCIES
Glass, live in your browser.
aave-glass refracts real page pixels behind an SVG displacement map. No screenshots, no video — the page you're reading is the demo, and the lens is already moving.
The technique is Aave's. The code is yours. feDisplacementMap displaces actual DOM — not a copy of it — so your text stays text, your links stay links, and your users never notice a thing except the glass.
DRAG IT YOURSELF
The lens bends pixels, not copies.
This is real document text, not a screenshot. The displacement map encodes a direction per pixel — red for horizontal, green for vertical, neutral 128 outside the lens — and an SVG feDisplacementMap moves the actual DOM pixels inside the region.
That is why the honest proof is selecting text under the glass: if this were a screenshot the selection would break. It doesn't. The document under the lens is the document.
Move the lens and the pixels bend with it. Release it and the text is still selectable, the link still clickable. Nothing here is painted; everything is displaced.
Click and drag the lens. Then triple-click the text under it.
GLASS THAT WORKS
Controls that stay controls.
A real switch. The glass is decoration; the state is real.
Toggles still toggle. Nothing here is a screenshot.
THE SANDBOX
Turn the lens into something else.
Four numbers. Same displacement map, regenerated only when the shape changes — moving costs nothing, reshaping costs one canvas pass.
text row one
second row
third row here
strength:30 chroma:0.35 size:150 radius:28
How it works
The map regenerates only when the lens shape changes. Moving it just shifts the filter region.
INSTALL · CONTRIBUTE
A few hundred bytes. That's the install.
<script type="module" src="glass.js"></script>
export function createGlass({ regionEl, lens, strength }) { ... }
There's no build. Drop the file in, add the script tag.
| Browser | SVG filter | Note |
|---|---|---|
| Chrome 84+ | ✓ | |
| Firefox 101+ | ✓ | |
| Safari 15.4+ | ✓ | use WebGL for video |
| Edge 84+ | ✓ |
Gotcha: Safari composites <video> on the GPU, so SVG filters can't reach those pixels. Use the WebGL fallback (glassWebGL.js) for video. Canvas has no live DOM to displace, so it always uses the WebGL path.