
Liquid Glass is a tiny JavaScript library that adds Apple-style Liquid Glass effects with refraction, edge distortion, and a prism fringe to any DOM element.
It’s ideal for translucent cards, floating navigation bars, buttons, toolbars, and compact overlays placed over visible page content.
Chromium browsers get the real SVG refraction. Safari and Firefox receive an automatic frosted-blur fallback.
Features:
- Apply iOS & macOS style refractive glass optics to any DOM element.
- Generate edge-focused displacement around a readable center.
- Add a restrained chromatic fringe along rounded borders.
- Switch unsupported browsers to a frosted blur treatment.
- Track element size changes and rebuild the optical map.
- Preserve selectable text and usable controls inside the panel.
How To Use It:
Installation
Download liquid-glass.js, and then place it in your HTML document.
<script src="liquid-glass.js"></script>
Basic Usage
Place the target element over a visible image, gradient, or page section. Keep its background translucent so the filtered backdrop remains visible.
<div class="weather-stage">
<section class="weather-panel">
<span class="weather-city">Seattle</span>
<strong class="weather-temp">68°F</strong>
<span class="weather-status">Light rain</span>
</section>
</div>
<script src="liquid-glass.js"></script>
<script>
// Apply the optical effect after the panel exists in the DOM.
const weatherGlass = liquidGlass(
document.querySelector(".weather-panel")
);
</script>
Add the material styling with CSS. The script reads the element’s corner radius when it builds the displacement map.
.weather-stage {
min-height: 360px;
display: grid;
place-items: center;
padding: 40px;
background:
radial-gradient(circle at 20% 30%, #f368e0 0 12%, transparent 35%),
radial-gradient(circle at 80% 65%, #48dbfb 0 16%, transparent 38%),
linear-gradient(135deg, #341f97, #0fbcf9);
}
.weather-panel {
width: min(320px, 80vw);
padding: 28px;
border-radius: 30px;
color: #fff;
background: linear-gradient(
180deg,
rgba(18, 20, 34, 0.16),
rgba(18, 20, 34, 0.32)
);
box-shadow:
0 24px 60px rgba(0, 0, 0, 0.35),
inset 0 1px 1px rgba(255, 255, 255, 0.55),
inset 0 -10px 22px rgba(255, 255, 255, 0.06),
inset 0 0 0 1px rgba(255, 255, 255, 0.16);
}
.weather-panel span,
.weather-panel strong {
display: block;
}
.weather-temp {
margin: 8px 0;
font-size: 3rem;
}
Advanced Usages
Soften Refraction Over Detailed Backgrounds
const profileGlass = liquidGlass(
document.querySelector(".profile-card"),
{
scale: -76,
chroma: 3,
border: 0.1,
mapBlur: 18,
blur: 8,
saturate: 1.25
}
);
Remove the Prism Fringe
const toolbarGlass = liquidGlass(
document.querySelector(".editor-toolbar"),
{
scale: -104,
chroma: 0,
blur: 4,
saturate: 1.2
}
);
Refresh After a Manual Layout Change
The built-in resize observer handles normal element resizing. Call the instance refresh method after an application changes dimensions through a custom state transition or delayed layout step.
const drawer = document.querySelector(".glass-drawer");
const drawerGlass = liquidGlass(drawer);
document.querySelector(".drawer-toggle").addEventListener("click", () => {
drawer.classList.toggle("is-expanded");
// Rebuild the displacement map after the width transition finishes.
drawer.addEventListener(
"transitionend",
() => drawerGlass.refresh(),
{ once: true }
);
});
Use Liquid Glass in React
Create the effect after the component mounts and remove it during cleanup. The element ref must point to a rendered DOM node.
import { useEffect, useRef } from "react";
export default function GlassSearchPanel() {
const panelRef = useRef(null);
useEffect(() => {
const panelGlass = window.liquidGlass(panelRef.current, {
scale: -90,
chroma: 4,
blur: 5
});
return () => panelGlass.destroy();
}, []);
return (
<section ref={panelRef} className="search-panel">
<label htmlFor="site-search">Search documentation</label>
<input id="site-search" type="search" />
</section>
);
}
All Configuration Options
scale(number): Sets displacement strength. Negative values create a magnifying bulge. The default is-112.chroma(number): Sets the scale difference between the red, green, and blue passes. Use0to remove the prism fringe. The default is6.border(number): Sets the neutral interior inset as a fraction of the element’s shorter side. The default is0.07.mapBlur(number): Sets the softness of the displacement map edge in pixels. Lower values produce a harder rim. Higher values produce a wider dome. The default is12.blur(number): Sets the backdrop blur inside the glass in pixels. The default is3.saturate(number): Sets the backdrop saturation multiplier. The default is1.5.radius(number or null): Overrides the corner radius used by the displacement map. Anullvalue reads the computedborder-radiusfrom the target element. The default isnull.fallbackBlur(number): Sets the frosted blur strength in Safari, Firefox, and other unsupported browsers. The default is16.
API Methods
// Check whether the browser uses the full SVG-filtered refraction path. glassInstance.supported; // Rebuild the displacement map after a manual size or radius change. glassInstance.refresh(); // Remove resize handling, delete the SVG filter, and clear the effect. glassInstance.destroy();
Implementation Tips:
- Initialize the effect after the target element enters the DOM.
- Keep the panel background translucent. An opaque fill hides the backdrop effect.
- Avoid global CSS rules that set hidden SVG elements to
display: none. - Keep glass elements below roughly 800 pixels per side for lower map-generation cost.
- Animate position instead of dimensions when possible. Position changes do not require a new displacement map.
- Lower refraction and chromatic intensity when background content becomes hard to read.
- Treat refraction as decoration. Important state, labels, and actions must remain clear in the fallback view.
Alternatives & Related Resources:
- WebGL Liquid Glass Effect for HTML Elements – LiquidGlass.js
- Create Liquid Glass Effects with Dynamic Displacement – GlassiFy
- Create Realistic iOS Liquid Glass Effects with SVG Filters and JS
- Create Advanced Liquid Glass and Noise Effects with FxFilterJS
- Create Apple Liquid Glass UI with Pure CSS and SVG Filter
- Apple’s Official iOS 27 and iPadOS 27 UI Kit for Figma
FAQs:
Q: Why does my glass panel look invisible even though the script ran?
A: The library only owns the refraction filter and blur. A background tint, box shadow, and border radius need to be set on the element in CSS, or the panel refracts content without reading as a glass surface.
Q: Why did the refraction disappear after I changed the text inside the panel?
A: If the change did not resize the element, the built-in resize observer never fires. Call glass.refresh() manually after any layout change that keeps the same box dimensions.
Q: Is the effect accessible?
A: The library keeps the original DOM content selectable and interactive, but it does not manage contrast or semantics. Keep text contrast high and treat the refraction layer as decorative.







