GlassSearchBar

A search capsule of real glass over a picture, bending and splitting what scrolls behind it.

scroll the picture behind the glass

Paste into Claude Code, Cursor or any agent. Pinned to a tag, so it will not change under you.

Options

glass #ffffff

css colour

The tint the glass leaves and the colour its highlights take. Near white unless the glass is meant to be coloured, because it is multiplied into the picture rather than painted over it.

panelX 0.5

0 to 1

Centre of the panel across the element.

panelY 0.82

0 to 1

Centre of the panel down the element.

panelWidth 0.44

0.05 to 1

Width of the panel as a share of the element.

panelHeight 0.115

0.03 to 1

Height of the panel as a share of the element.

radius 200

0 to 200

Corner radius in CSS pixels, capped at half the shorter side, so a large number gives a capsule rather than an error.

bevel 14

1 to 120

How far in from the edge the bevel reaches. This is the width of the band that bends: the middle of a slab is flat and refracts nothing, which is why the centre stays readable and only the rim distorts.

refraction 30

0 to 120

How far the bevel bends what is behind it, in pixels. At 0 you have frosted glass, and this is the setting that makes it glass rather than a blur.

dispersion 6

0 to 30

How far the three channels separate as they bend. Glass has a different refractive index per wavelength, which is why a real edge fringes, and it is the cheapest thing that stops a shape reading as plastic. Past about 12 it stops being glass and starts being a prism.

frost 2

0 to 40

Frosting, as a blur radius in pixels. Twelve taps on a ring, which is not a Gaussian and does not need to be.

specular 0.35

0 to 2

How brightly the bevel catches the light. The highlight is lit off a real normal built from the distance field, so it moves round the rim as the light does rather than sitting where it was painted.

shine 40

1 to 160

How tight that catch is. Low is a broad satin sheen along the whole bevel; high is a small hard glint at the point facing the light.

fresnel 0.06

0 to 1.5

How much the rim brightens where you are looking through the most glass. This is what gives the edge its thickness.

edge 0.25

0 to 1.5

The bright hairline just inside the edge, where the bevel turns over.

tint 0.22

0 to 1

How much colour the glass leaves on what passes through it. This is also the contrast control if anything is going to be read on top of the panel.

luminosity 0.62

0 to 1

How far the backdrop's brightness is pulled toward `level` before the glass is drawn. This is what makes anything readable on the panel, and it is a compression rather than a wash: the luminance moves, the hue and the detail do not, so the picture is still a picture. Windows Acrylic calls this the luminosity layer and it is the part that guarantees contrast. At 0 the glass is clear and nothing is safe to put on it.

level 0.13

0 to 1

The brightness the backdrop is pulled toward. Low dims it, which suits light labels and is how a clear glass control is made legible: dimming a photograph leaves it looking like a photograph, and milking it toward white does not. High milks it, for dark labels. It is the one number that decides which way round the glass works, and the labels have to follow it.

lightX -0.5

-2 to 2

Where the light is, across the panel.

lightY 0.7

-2 to 2

Where the light is, down the panel.

shadow 22

0 to 80

How far the shadow under the slab reaches. Without it the panel is a window cut in the picture rather than an object resting on it.

travel 1

0 to 3

How far the picture travels behind the glass over a full scroll, as a share of the slack the cover fit left. At 0 the picture is fixed and all the glass has to bend is a still.

What it needs

Category
Surfaces, an effect
Dependencies
None at all
Browser
WEBGL2
Frame budget
~1.6 ms · 1 context
Pinned to
v0.12.0
  • The picture is the host element's own <img> child. It is hidden from sight and left in the document, so the alt text is whatever you wrote and a page with no JavaScript still shows it
  • This is WebGL rather than CSS because backdrop-filter can blur what is behind an element but cannot bend it, and bending is most of what glass is. The one CSS route that bends, an SVG displacement filter on the backdrop, is Chromium only and fails silently everywhere else
  • The trade is that the panel owns its backdrop: it refracts the picture it was given rather than arbitrary page content. Anything that has to sit on top goes in the DOM above the canvas
  • The slab is a signed distance field for a rounded rectangle, and its gradient is analytic rather than sampled, because an approximate normal shows up at once as a wobble along the straight runs
  • Dispersion is three samples at three offsets along that normal, taken per tap inside the blur so the fringe survives it rather than being averaged away
  • One WebGL2 context, one full-screen triangle, no buffers and no attributes
  • Legibility is a luminosity compression rather than a tint: the backdrop's brightness is scaled toward a level, so the hue and the detail survive. Mixing toward white measures the same and looks dead, because it desaturates the picture and flattens what the glass is supposed to be bending
  • The material belongs to the layer floating above content rather than to content itself, which is the rule Apple states for it, so what sits on the panel is a control: a search field, a toolbar, a nav. The demo is a search capsule, inset and low in the frame, which is where a thumb reaches
  • Legibility is a dimming layer with light labels rather than a milky one with dark labels. A darkened photograph still looks like a photograph because the hue and the tonal relationships survive, and a whitened one does not. It is also what Apple gives its Clear variant, which has no adaptive behaviour of its own
  • Measured against the brightest tile under the capsule, since white text is hardest where the backdrop is lightest: solid labels come out at 5.3:1 and the secondary ones at 4.79:1. The magnifier, the placeholder and the hint had all been set by eye and all three measured short while the field text passed
  • Outside the panel it is one texture read per pixel. Everything expensive is inside a branch that most of the frame never takes
  • Inside: twelve taps on a ring, three channels each, so thirty-six texture reads. That is the cost of frosted glass whose dispersion survives the blur
  • The image uploads once, on load. Nothing is uploaded per frame