Lighting
Light that behaves like light.
The rim is lit as a curved surface. A specular highlight catches the light, and fresnel brightens the edge where the glass turns away from you.
REAL HTML · EVERY BROWSER · NO DEPENDENCIES
This text is real. Select it, Cmd+F it, click the buttons.
Drop an image to look through the glass
Not a screenshot, not a canvas. The lens refracts the live page, so text stays selectable and buttons stay clickable. In Chrome, Firefox and Safari.
Lighting
The rim is lit as a curved surface. A specular highlight catches the light, and fresnel brightens the edge where the glass turns away from you.
Bevel
Set how far the curve reaches in. Take it all the way to the middle and the lens becomes a magnifier. Move over it.Drag it around.
Button mode
Hover and the glass brightens. Press and the bevel flattens as the shadow tightens. Springs, so it never snaps.
Tone
Grade what's behind the lens without touching the page.
Presets
Pick one, then tune it. Presets are plain settings on LiquidGlass.presets, so your site can use them too.
0
dependencies
1
file to copy
3
browser engines
Four stages, all standard web platform: a copy of the page, a map of how far each pixel moves, an SVG filter that moves them, and light painted on top.
Step 1 · Copy
An SVG filter can't see what's behind an element. backdrop-filter: url() could, but only Chrome supports it. So the lens keeps its own copy of the page, made with cloneNode(true) and positioned so every pixel lines up with the original.
A MutationObserver, plus input and scroll listeners, marks the copy stale, and it's rebuilt on the next frame. Cloning drops live state, so input values, checkboxes, canvas pixels and scroll offsets are carried across by hand.
Step 2 · Map
The lens is a signed distance field for a rounded rectangle: negative inside, zero on the edge. Across the bevel the glass is a quarter circle, so the bend grows as 1 − √(1 − t²), where t runs from 0 at the bevel's inner edge to 1 at the rim. The direction is the field's gradient, which points straight out.
Each offset is written to a canvas, x in red and y in green, centred on 128. The curve stops just short of vertical, since a vertical edge would bend without limit.
Step 3 · Filter
Real glass bends each wavelength a little differently. The filter runs the displacement three times at slightly different strengths, keeps red from the strongest, green from the middle and blue from the weakest, then adds them back together.
Brightness and saturation are one colour matrix at the end. Frost is a CSS blur() around the filter rather than feGaussianBlur inside it, which keeps it on the GPU in Firefox.
Step 4 · Light
Lighting is a canvas over the glass. Each rim pixel gets a 3D normal that tilts outward as the bevel rounds over. A Blinn-Phong half vector between a top-left light and your eye gives the specular spot, and fresnel brightens the edge where the surface turns away.
It's drawn at device resolution when the shape changes, never per frame. Moving the lens is only a transform.
The frame loop checks three flags: the copy is stale, the shape changed, or the lens moved. On an idle frame it does nothing.
Position is a damped spring, so new input just retargets it mid-flight. Speed stretches the lens along its path, and reduced motion snaps instead.
Map channels are 8-bit, so zoom stored there moved in half-pixel steps. Instead the filtered layer is built at 1/zoom size and scaled up.
Browsers rasterise filters on the CSS pixel grid. At a fractional position the refraction gets resampled and shimmers, so the lens snaps to whole pixels.
Safari drops a filter over GPU layers and mis-scales transformed content inside one. The copy loses will-change and animations, and moves with left and top.
Screen readers, keyboard focus and find-in-page only ever meet the real page. The copy is inert and hidden, and its IDs are stripped so they stay unique.
Liquid glass on the web, side by side. Each takes a different path to the same look, and each path has its trade-offs.
From each project's README and source in October 2026. Libraries change, so check the links for the latest. Our copy doesn't show hover or focus states, video or WebGL canvases.
Tune the lens and this code follows along. No build step, no dependencies. Copy the snippet, or download a page that runs on its own.
You're using an uploaded image. Swap your-image.jpg for a URL on your site.
Using a bundler? Import src/glass.js directly. View on GitHub