Every glassmorphism snippet I’ve seen is backdrop-filter: blur() plus a white overlay. That’s a blurred rectangle. Real glass bends what’s behind it, hardest at the edge — and that part is missing everywhere.
Built it for a production Angular app, pulled it out as a Claude Code plugin: https://github.com/stormaref/LiquidGlassSkill
/plugin marketplace add stormaref/LiquidGlassSkill
/plugin install liquid-glass@stormaref-skills
The refraction: bake a displacement map into a canvas, wire up feImage → feDisplacementMap → feGaussianBlur, point the element at it with backdrop-filter: url(#filter). Since it’s a backdrop filter, the input is the live page behind the element — so it tracks scroll, theme and content changes with nothing to invalidate. Field ported from liquid-glass-js (MIT, credited), minus its html2canvas snapshot.
Why it’s a skill and not a gist — four rules, each of which fails as plausible-looking output:
- Glass needs a backdrop. Over a flat page it reads as a gray box, which sends you reaching for more blur — the exact move that kills it.
- The tint is colorless. Hue in the tint fights the hue coming through; the surface goes muddy.
- Children of a glass panel paint no surface. An opaque fill covers the refracted backdrop, which is the whole effect.
-
You can’t feature-query it. Safari parses
backdrop-filter: url(#…)and paints nothing, so@supportssays yes and your panel is blank. Gate on engine.
The CSS is 200 lines. Knowing that #1 is why your glass looks nths of things looking subtly wrong.
MIT. Happy to talk displacement math — the 128/255 ≠ 0.5 decly long to find.