glass-lens

Refraction for live DOM, in every browser

One SVG feDisplacementMap, a generated lens map, and the unit system every browser actually understands. No canvas, no clones, no WebGL, no flags — the glass bends the page's own pixels, so text stays selectable and links stay clickable straight through the lens.

Move your pointer over this card

refractionzero dependencies Chromium ✓Safari ✓Firefox ✓

Everything under the lens is real, rendered DOM. Try drag-selecting this paragraph through the distortion, or clicking this link. The effect samples nothing from behind a pane — the content's own pixels are the ones moving.

Pinned to a real component

No pointer required. Here the lens is a static glass pill sized to one segment of a segmented control; selecting a tab glides it across the control's own pixels — the same pattern native iOS uses. Cross-browser, and every tab stays clickable straight through the glass.

Glass navigation over a scrolling page

A real-world layout: a bar fixed to the top of a scrolling page, with the content sliding behind it picking up the glass. Scroll inside the frame — the bar refracts whatever passes under it, live. Cross-browser, no backdrop-filter. (One caveat below on how this scales.)

The Aurora Field Guide

Scroll this panel. The glass bar above stays put while the article travels underneath it, refracting through the lens as it goes.

Northern Lights

Auroras form when charged particles from the sun collide with gases high in the atmosphere. Greens come from oxygen near 100 km; reds from oxygen much higher up; blues and violets from nitrogen.

Where to look

The band of best viewing sits roughly between 65° and 72° magnetic latitude — a ring over northern Canada, Iceland, Norway, and Siberia.

Solar Wind

Activity tracks the eleven-year solar cycle. Near the peak, displays push to lower latitudes and turn brighter and more frequent.

Reading the forecast

The Kp index runs 0–9. A Kp of 5 or more means a geomagnetic storm and a real chance of color overhead far from the poles.

Long Exposure

A tripod and a multi-second exposure pull out color the eye can barely register. Start near f/2.8, ISO 1600, 10 seconds, and adjust from there.

Keep scrolling — the refraction tracks every line of this text as it slides under the bar, because the glass is bending the page's own pixels.

One more thing

The bar isn't sampling a blurred backdrop. It's the same SVG displacement filter from the demos above, pinned to the top of this scroll container and refreshed as you scroll.

✦ Aurora GuideSkyGear

Scales fine for a contained panel like this. For a full, heavy page, see the note in the README — putting an SVG filter on a large scroll container forces the browser to re-rasterize its content, so a production glass nav is better done with a small fixed strip.

How it works

The lens map is a small PNG generated on a canvas: its red channel encodes horizontal displacement, green encodes vertical, and 128 means "don't move." An SVG filter loads it with feImage, composites it over neutral gray, and hands it to feDisplacementMap, which bends the element's own rendered pixels. A final mask sandwich — punch a lens-shaped hole in the original, lay the displaced result over it — keeps the effect confined to the lens with an invisible seam.

The cross-browser trick is a single attribute: every geometric value in the filter is expressed in objectBoundingBox fractions. WebKit cannot resolve userSpaceOnUse pixel geometry for filter primitives applied to HTML elements — feImage and primitive subregions silently fail — but in bounding-box fractions the entire primitive set works. Two more details keep the result identical across browsers: the map image is fully decoded before the filter attaches, and the filter gets a fresh ID on every update, so no browser serves stale cached filter output.

Moving the lens is nearly free. The map never regenerates on movement — only the fractional subregions of three primitives shift. The map is rebuilt only when the lens changes shape, and even then only one quadrant is computed; the rest is mirrored.