Select a file from the tree to view its contents.
glass.md
This file is a practical guide for creating the Liquid Glass effect used by rdev/liquid-glass-react.
What the effect actually is
This library does not just add blur and call it glass. It combines:
- A displacement map to bend the background like liquid
- Backdrop blur and saturation to create the frosted glass body
- Chromatic aberration on the edges for the Apple-like refracted look
- Mouse-driven elasticity so the shape reacts like soft material
The repo exposes a React component called LiquidGlass and supports React 18+ as a peer dependency. The README also notes that Safari and Firefox only partially support the effect, and displacement is not fully visible there.
Requirements
Before using the effect, make sure you have:
- React 18 or newer
- React DOM 18 or newer
- A browser with good support for
backdrop-filterand SVG filters - A layout where the glass element can sit above visible background content
Install the package:
npm install liquid-glass-react
If you are building your own version from scratch, you will also need:
- TypeScript
- A rendering target that supports SVG filter primitives
- Mouse tracking logic if you want the elastic motion
- Good layered backgrounds, because glass over a flat background looks fake fast
Basic usage
The simplest usage is to wrap any content in LiquidGlass.
import LiquidGlass from "liquid-glass-react"
function App() {
return (
<LiquidGlass>
<div className="p-6">
<h2>Your content here</h2>
<p>This will have the liquid glass effect</p>
</div>
</LiquidGlass>
)
}
What matters here
- The children are still normal React nodes
- The glass effect is applied around the children, not inside them
- The component handles positioning, transform, and filter work for you
Button-style glass
This repo shows a tighter configuration for pill buttons.
<LiquidGlass
displacementScale={64}
blurAmount={0.1}
saturation={130}
aberrationIntensity={2}
elasticity={0.35}
cornerRadius={100}
padding="8px 16px"
onClick={() => console.log("Button clicked!")}
>
<span className="text-white font-medium">Click Me</span>
</LiquidGlass>
Use this style when:
- The component is small
- You want a tactile hover and click feel
- You want stronger refraction on the edges
Mouse container mode
If you want the glass to react to mouse movement across a larger region, pass mouseContainer.
import { useRef } from "react"
import LiquidGlass from "liquid-glass-react"
function App() {
const containerRef = useRef<HTMLDivElement>(null)
return (
<div ref={containerRef} className="w-full h-screen bg-image">
<LiquidGlass
mouseContainer={containerRef}
elasticity={0.3}
style={{ position: "fixed", top: "50%", left: "50%" }}
>
<div className="p-6">
<h2>Glass responds to mouse anywhere in the container</h2>
</div>
</LiquidGlass>
</div>
)
}
This is the right pattern when:
- The glass is floating over a large visual scene
- You want one parent area to drive the effect
- You do not want the mouse tracking limited to the element itself
If you are building the effect yourself
This is the important part. Do not fake it with only:
backdrop-filter: blur(20px);
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
That is regular frosted glass. It is not liquid glass.
A real liquid glass effect needs the following pipeline:
- Render a displacement map
- Feed that map into an SVG filter
- Use
feDisplacementMapto bend the content - Add
backdrop-filterblur and saturation - Split channels slightly to create color fringing
- Animate transform based on pointer position
Core implementation pattern
1. Keep the glass container relative
The wrapper should be positioned in a predictable way so you can layer filters and content inside it.
<div className="relative">
<LiquidGlass>
<div>Content</div>
</LiquidGlass>
</div>
2. Use a backdrop layer and a sharp content layer
The effect works best when the background is warped, but the foreground text stays crisp.
<div className="glass">
<span className="glass__warp" />
<div className="glass__content">Sharp content here</div>
</div>
3. Use SVG filter primitives for refraction
The repo uses a filter chain around feImage, feDisplacementMap, feBlend, and feComposite.
A simplified version looks like this:
<svg style={{ position: "absolute", width: 0, height: 0 }} aria-hidden="true">
<defs>
<filter id="liquid-glass">
<feImage href={displacementMapUrl} result="map" />
<feDisplacementMap
in="SourceGraphic"
in2="map"
scale={70}
xChannelSelector="R"
yChannelSelector="B"
/>
</filter>
</defs>
</svg>
That is the part that makes the edges bend instead of just blurring.
4. Add backdrop blur and saturation
This is the frosting layer.
style={{
backdropFilter: "blur(20px) saturate(140%)",
}}
5. Add elastic motion
The repo tracks pointer position and uses it to compute a transform.
const transform = `translate(calc(-50% + ${x}px), calc(-50% + ${y}px)) scale(${scale})`
The point is simple:
- The element should stretch slightly toward the pointer
- The motion should fade out when the pointer is far away
- The stronger the elasticity, the more alive the material feels
Prop guide
These are the props exposed by the library and what they are for:
| Prop | Purpose | Good starting value |
|---|---|---|
displacementScale |
Strength of the background warp | 70 for large surfaces, 40-64 for buttons |
blurAmount |
Frosted blur amount | 0.0625 default, higher for heavier blur |
saturation |
Color boost inside the glass | 140 to 180 |
aberrationIntensity |
Chromatic edge split | 1.5 to 2.5 |
elasticity |
How soft the movement feels | 0.15 default, 0.3+ for buttons |
cornerRadius |
Border radius in pixels | 999 for pills, 24-40 for cards |
padding |
Internal spacing | 24px 32px or smaller for buttons |
overLight |
Tune for bright backdrops | true on white or pale backgrounds |
mode |
Displacement mode | standard first, then shader if needed |
mouseContainer |
Parent area for pointer tracking | useRef container for scene-driven layouts |
Best practices
Use a real background
Glass looks bad on a flat canvas. Put it over:
- a gradient
- an image
- a dense UI
- layered shapes with contrast
Keep text readable
Do not bury text inside a noisy effect. Use:
<div className="relative z-10 text-white">
Content
</div>
Use stronger blur on bright surfaces
The repo exposes overLight for exactly this reason. Bright backgrounds need more blur and stronger shadowing to keep contrast usable.
Do not overdo chromatic aberration
If the color split is too strong, the element starts looking broken instead of premium.
Respect browser limitations
The README warns that Safari and Firefox only partially support the effect, especially the displacement part. That means:
- test the fallback
- do not rely on identical rendering everywhere
- avoid hard dependencies on the full effect for critical UI
Minimal DIY version
If you only want the look and do not care about the exact interaction model, this is the minimum viable version:
export function SimpleGlass({ children }: { children: React.ReactNode }) {
return (
<div
style={{
position: "relative",
borderRadius: 32,
overflow: "hidden",
background: "rgba(255,255,255,0.08)",
backdropFilter: "blur(24px) saturate(150%)",
border: "1px solid rgba(255,255,255,0.18)",
boxShadow: "0 12px 40px rgba(0,0,0,0.25)",
padding: "24px 32px",
}}
>
<div style={{ position: "relative", zIndex: 1, color: "white" }}>
{children}
</div>
</div>
)
}
That is not full liquid glass, but it is a clean starting point.
Better DIY version with displacement
If you want closer behavior, you need a displacement map.
const displacementMapUrl = "data:image/jpeg;base64,..."
export function GlassWithFilter({ children }: { children: React.ReactNode }) {
return (
<>
<svg style={{ position: "absolute", width: 0, height: 0 }} aria-hidden="true">
<defs>
<filter id="glass-filter">
<feImage href={displacementMapUrl} result="map" />
<feDisplacementMap
in="SourceGraphic"
in2="map"
scale={70}
xChannelSelector="R"
yChannelSelector="B"
/>
</filter>
</defs>
</svg>
<div
style={{
filter: "url(#glass-filter)",
backdropFilter: "blur(20px) saturate(140%)",
borderRadius: 32,
overflow: "hidden",
}}
>
{children}
</div>
</>
)
}
That gets you much closer to a real liquid-like bend.
Implementation checklist
Before calling the effect done, confirm these are all true:
- The background behind the element is visually rich
- Blur and saturation are applied
- The glass has a rounded shape
- There is a warp or displacement layer
- The foreground text remains readable
- Hover and click feel natural
- The layout still works on smaller screens
- Safari and Firefox fallbacks are acceptable
What not to do
Do not:
- apply the effect to huge walls of text
- ignore browser support
- use giant displacement values everywhere
- make the content unreadable
- use the effect where a normal card would be better
This is a visual accent, not a default UI style.
Recommended starting presets
Card
<LiquidGlass
displacementScale={48}
blurAmount={0.08}
saturation={150}
aberrationIntensity={1.8}
elasticity={0.18}
cornerRadius={32}
padding="24px 28px"
>
<div>Your card content</div>
</LiquidGlass>
Button
<LiquidGlass
displacementScale={64}
blurAmount={0.1}
saturation={130}
aberrationIntensity={2}
elasticity={0.35}
cornerRadius={999}
padding="10px 18px"
>
<span>Action</span>
</LiquidGlass>
Floating panel
<LiquidGlass
displacementScale={56}
blurAmount={0.06}
saturation={140}
aberrationIntensity={1.5}
elasticity={0.22}
cornerRadius={40}
padding="28px 32px"
overLight={false}
>
<div>Panel content</div>
</LiquidGlass>
Bottom line
If you want the Apple-like liquid glass feel, the trick is not just blur. It is the combination of:
- displacement
- edge refraction
- slight chromatic aberration
- elastic pointer response
- a strong visual background
That is what makes the effect look expensive instead of amateur.
About
No description provided for this skill.