Real glass bends,
blur only averages.
Blur takes the pixels behind your panel and averages them. Result: a grey rectangle with frosted film.
Glass shifts every backdrop pixel sideways: light that gets refracted. That's exactly what this SVG filter does, live, behind this card.
↓ scroll for the comparison · drag the round lens anywhere on the page: the waves give way beneath it
Same background. Two physics.
Both panels sit over the same slowly rolling waves. On the left the standard look, on the right the full stack. Watch the glowing wave crests as they drift under the panels.
backdrop-filter: blur(14px)
Average of the pixels. Detail gone, contrast gone, material gone. The wave crests behind turn to fog: flat gray rectangle.
url(#bend) + blur(2px) + 1px edge
The crests kink and refract as if thick glass lay over them. Plus the white inner edge at the top: the lit face of the pane.
Turn the glass
The sliders write live into the SVG filter. Every glass surface on the page (cards and lens) hangs off the same #bend.
Three ingredients, no framework
feTurbulencecreates a noise texture: the micro-surface of the glass pane.feDisplacementMapreads the noise and shifts every backdrop pixel sideways: the R channel drives X, the G channel drives Y. That's the refraction.- The filter goes into
backdrop-filterviaurl(#bend), right next to a small blur. Then a1pxwhite inner edge as the lit face, and the div becomes an object.
<!-- 1 + 2: the pane -->
<svg width="0" height="0">
<filter id="bend">
<feTurbulence type="fractalNoise" baseFrequency="0.012 0.016"
numOctaves="2" result="noise"/>
<feGaussianBlur in="noise" stdDeviation="2" result="soft"/>
<feDisplacementMap in="SourceGraphic" in2="soft" scale="90"
xChannelSelector="R" yChannelSelector="G"/>
</filter>
</svg>
/* 3: the object */
.glass {
backdrop-filter: url(#bend) blur(2px) saturate(1.6);
border: 1px solid rgba(255,255,255,.35);
box-shadow:
inset 0 1px 0 rgba(255,255,255,.65), /* lit edge */
inset 0 -1px 0 rgba(255,255,255,.12),
0 24px 60px rgba(0,0,0,.45);
}
Heads-up: backdrop-filter: url(…) with SVG filters currently only renders in Chromium browsers. Safari & Firefox show the blur fallback, one more reason flat grey rectangles are everywhere.