Same title—how do I do this? I just can’t get it to work.
How are Liquid Glass and immersive lighting effects implemented on the web? @grokbot
Implementing “Liquid Glass + Immersive Lighting” on the Web essentially involves stacking three layers of technology:
- Frosted glass base ——
backdrop-filterfor blur and saturation enhancement - Edge refraction —— SVG
feDisplacementMapmakes the background produce a “liquid” distortion around the glass edges - Lighting layer —— Highlight outlines, a pointer-following radial light source, a dynamic ambient background + grain
The layers are broken down below, and you can copy the code directly.
1. Frosted glass base (the most basic layer)
.glass {
position: relative;
border-radius: 24px;
/* Semi-transparent base color: the blurred area needs a little base color, otherwise the blur effect looks washed out */
background: rgba(255, 255, 255, 0.12);
/* Core effect: blur + saturation enhancement (saturate makes the colors behind the glass look more vivid) */
-webkit-backdrop-filter: blur(20px) saturate(180%);
backdrop-filter: blur(20px) saturate(180%);
/* 1px inner border simulating the thickness of glass */
border: 1px solid rgba(255, 255, 255, 0.22);
/* Outer shadow + top highlight; without either one, it won't look like glass */
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.18),
inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
saturate(180%)is the key to the “translucent” feel of liquid glass—don’t just writeblur().
2. Edge refraction — the soul of “liquid”
Pure blur is just frosted glass (glassmorphism). The defining feature of true Liquid Glass is that the edges distort the background like a lens. This can only be done with an SVG filter to create displacement, then fed into backdrop-filter:
<svg width="0" height="0" style="position:absolute">
<filter id="liquid" x="-25%" y="-25%" width="150%" height="150%"
color-interpolation-filters="sRGB">
<!-- Noise field: determines the direction of the distortion -->
<feTurbulence type="fractalNoise"
baseFrequency="0.008 0.012"
numOctaves="2" seed="7" result="noise"/>
<!-- Smooth it slightly to avoid overly harsh distortion -->
<feGaussianBlur in="noise" stdDeviation="3" result="smooth"/>
<!-- Displacement: scale controls the distortion strength -->
<feDisplacementMap in="SourceGraphic" in2="smooth"
scale="40"
xChannelSelector="R" yChannelSelector="G"/>
</filter>
</svg>
.liquid {
backdrop-filter: url(#liquid) blur(12px) saturate(180%);
-webkit-backdrop-filter: blur(12px) saturate(180%); /* Safari fallback */
}
To make the distortion appear only around the edges (while keeping the center clear), use a radial gradient image as the input for the displacement map: gray in the center (no displacement), red/green at the edges (strong displacement). This produces true liquid glass with “lens-like edges and a clear center.”
To be honest about compatibility:
url(#...)insidebackdrop-filtercurrently works in Chrome / Edge / Firefox, but Safari basically doesn’t support it (-webkit-backdrop-filteronly accepts a list of functions). So be sure to add an@supportsbranch. Safari users will see a pure frosted-glass version—a slightly reduced effect, but nothing will break.
3. Lighting layer — highlights, light sources, and grain
1. Pointer-following highlight (the main source of immersion)
.glass::before {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
pointer-events: none;
background: radial-gradient(
240px circle at var(--mx, 50%) var(--my, 0%),
rgba(255, 255, 255, 0.35),
transparent 65%
);
}
el.addEventListener('pointermove', e => {
const r = el.getBoundingClientRect();
el.style.setProperty('--mx', `${e.clientX - r.left}px`);
el.style.setProperty('--my', `${e.clientY - r.top}px`);
});
2. Dynamic ambient background (without a good-looking background, glass will never look good)
Liquid glass is “environment-dependent”—the background must contain highly saturated color blocks with variations in light and dark to create a sense of material:
body {
background:
radial-gradient(600px at 20% 30%, #ff7a59, transparent 60%),
radial-gradient(700px at 80% 20%, #4f7cff, transparent 60%),
radial-gradient(600px at 50% 90%, #b44cff, transparent 60%),
#0b0f1c;
animation: drift 18s ease-in-out infinite alternate;
}
@keyframes drift {
to { background-position: 60px -40px, -50px 30px, 20px 60px; }
}
3. Grain / noise (prevents banding in gradients and looks more like a real material)
.grain::after {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
opacity: 0.05;
pointer-events: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
4. Multilayered depth of field
Use different blur values for glass at different depths (blur(8px) in the foreground and blur(28px) in the background), along with different opacity levels, and the sense of space will appear immediately.
4. Performance and compatibility (especially important on mobile)
backdrop-filteruses per-frame GPU compositing. Once there are more than ~8–10 glass elements on screen, frame rates will start dropping; on list pages, it’s best to mount it only on visible items.- Don’t animate the
blur()value (for example, transitioning from 20px to 30px on hover). Use transform/opacity instead, or switch classes directly. - Safari has a limit on the number of backdrop-filter layers; beyond that, they simply won’t render. Consider adding
contain: paint;orisolation: isolateto constrain the compositing layers. - Provide a fallback:
@supports not (backdrop-filter: blur(1px)) {
.glass { background: rgba(255,255,255,.75); }
}
- Respect
prefers-reduced-motionand disable the background drift animation.
5. If you want to save time
- Ready-made libraries: Liquid Glass (npm
liquid-glass) andglassmorphismgenerators can automatically generate SVG refraction filters and the corresponding CSS. - Reference implementations: the
liquidglassproject by sharplab and the descriptions of “thickness, refractive index, and highlight angle” in Apple’s official Liquid Glass design guidelines (related SF Symbols / WWDC25 materials) are well worth studying alongside your implementation.
In one sentence: backdrop-filter handles “translucency,” SVG feDisplacementMap handles “liquid,” and radial highlights + a dynamic gradient background + grain handle “light.” Once all three are in place, the effect is essentially solid. If you share the specific use case (navigation bar / card / full-screen panel), I can provide a more tailored implementation.
There’s “glass” on the L site at topic/2891295/5, but I won’t post the exact link.
Tailwind + Bootstrap hybrid
Search here
hunt.now
Just bookmarking this.