A gradient changes the background along a line or outward from a point. A mesh spreads several colors across an area. Glass is a translucent layer that blurs whatever is behind it. They can be combined, but each one answers a different need, and each one fails in its own way.
What each one is made of
All three are plain CSS, which matters when you are deciding: you are choosing between a few lines of background code, not between libraries.
/* Gradient: one background image, one direction */
.gradient {
background-image: linear-gradient(to right, #ecc3a0, #91b8e4);
}
/* Mesh: several radial gradients stacked over a base color.
CSS has no native mesh gradient; this layering is the usual approach. */
.mesh {
background:
radial-gradient(at 18% 20%, #47e4e0 0px, transparent 50%),
radial-gradient(at 80% 16%, #5f81e4 0px, transparent 50%),
radial-gradient(at 74% 82%, #f67ff5 0px, transparent 50%),
#3b3486;
}
/* Glass: a translucent fill plus a filter on what sits behind it */
.glass {
background: rgb(255 255 255 / 0.6);
backdrop-filter: blur(16px) saturate(150%);
}The first two paint the element's own background. Glass is different: backdrop-filter changes the pixels behind the element, so it only shows anything when there is something visible underneath and the element's own background is at least partly transparent.
Gradients give color a direction
A linear gradient moves between colors along an angle. A radial gradient moves outward from a point. A conic gradient sweeps around a center. Linear and radial are the useful ones for backgrounds; conic is mostly for charts, rings, and decorative accents.
Use a gradient when you want a predictable transition: across a section, behind a title, on a button, or as a thin accent line. Two or three stops are usually enough. More stops make the transition harder to control and the hard part, the area behind the text, harder to keep consistent.
Watch the middle of the gradient
When every color in a gradient is written in legacy syntax (hex, rgb(), hsl(), or named colors), browsers blend in sRGB. Between two saturated, distant hues that produces a dull midpoint. Rendered in Chrome, the midpoint of linear-gradient(to right, #ff0000, #0000ff) is rgb(126 0 128), a dark purple. Adding in oklab moves the same midpoint to rgb(139 83 162), which is lighter and keeps more of both colors.
/* sRGB blending (default for hex colors) */
.hero { background-image: linear-gradient(to right, #ff0000, #0000ff); }
/* Oklab blending: same stops, brighter midpoint */
.hero { background-image: linear-gradient(to right in oklab, #ff0000, #0000ff); }Tailwind CSS v4 adds the interpolation method for you. bg-linear-to-r compiles to a gradient position of "to right in oklab" in browsers that support it. If you copy hex stops from a Tailwind design into plain CSS, or the other way round, the result can look different even though the colors are identical. Pick one and match it in both places.
Common gradient mistakes
- Checking text contrast only against one end. Text that spans a gradient has to pass against the lightest and darkest colors it sits on.
- Running a very subtle dark gradient across a full-width section. Small color differences spread over many pixels can show visible steps on some displays. A larger difference between stops, or a shorter run, usually helps.
- Using the gradient as the only thing that makes a button look clickable. The label and the shape should still read as a button if the gradient is removed.
The background gradient generator returns the same gradient as one CSS declaration, as Tailwind classes (Tailwind colors stay as tokens like from-blue-500, custom colors become arbitrary values like from-[#3b82f6]), or as an AI prompt describing the direction and stops.
Mesh makes a softer backdrop
A mesh blends several areas of color with no single direction. It suits a large background with room for the color to spread: a hero, a sign-up page, a section break. It is a poor fit for small elements, where the separate color areas have no room and it reads as a smudge.
Each layer in the CSS above is an ellipse centered on its at x% y% position. It starts as a solid color and fades to transparent at 50% of the gradient size. Three details control the result:
- Layer order. The first layer in the list paints on top. Moving a color earlier makes it dominate where it overlaps others.
- The transparent stop. Raising 50% to 65% makes each color spread further and the mesh softer; lowering it makes distinct blobs.
- The base color. Wherever every layer has faded out, the last value in the list shows through. A dark base gives depth; a light base makes the mesh look washed out.
Three or four color points cover most needs. Before adding a fifth color, try moving or resizing the ones you have. Decide where the heading will sit and keep the most saturated point away from it, or anchor the strong colors to the corners and leave the text area closer to the base color.
In the mesh gradient generator you drag numbered points over the preview to move each color, with between two and eight points. Copy the CSS when the mesh will live in a page: it is a single background declaration that scales to any size. Download the PNG when the destination does not take CSS, such as an email, a social image, or a design file.
Glass needs something behind it
Glass combines a translucent fill, background blur, and usually a thin light border. The effect comes from the material behind the panel. Over a flat color, a glass panel looks like a slightly lighter rectangle, and the blur costs rendering work for nothing.
It works where content moves or varies underneath: a navigation bar over a scrolling page, a dialog over a photo, a card over a mesh. In those cases the blur tells the reader that the panel floats above something, while keeping the panel's own text readable.
- Keep glass panels few and reasonably small. Background blur has to be recomputed when what is behind it changes, so large or stacked glass layers over animated content can make scrolling less smooth on slower devices.
- Measure text contrast against the brightest and darkest areas the panel can sit over, not against the tint color alone.
- Start from a solid fill and add translucency inside @supports (backdrop-filter: blur(1px)), so the panel stays readable where the filter is unavailable.
The liquid glass generator starts from 20 presets and lets you preview over its backdrops or your own image (the file stays in your browser). CSS export returns a .liquid-glass class with the -webkit- prefix and highlight layers; Tailwind v4 export returns one div of utilities and leaves out the chromatic edge and noise. Neither export adds a fallback, so add the @supports block yourself.
Which one to use
- A section needs color and the text has to stay easy to verify: a two-stop gradient, or a solid color.
- A large background with no photo or product image to fill it: a mesh with three or four points.
- UI that floats over changing content, such as a sticky header or a dialog over imagery: glass, with a solid fallback.
- Dense reading content, forms, or tables: a solid surface. Any of the three behind long text makes reading harder for little gain.
- A small accent such as a divider, badge, or focus ring: a linear gradient, kept short.
Combining a mesh and a glass panel
The most common combination is a mesh background with a glass card on top. The mesh gives the blur something to work with, and the card gives the text a calmer surface than the mesh alone.
<section class="relative overflow-hidden rounded-2xl px-6 py-10"
style="background:
radial-gradient(at 18% 20%, #47e4e0 0px, transparent 50%),
radial-gradient(at 80% 16%, #5f81e4 0px, transparent 50%),
radial-gradient(at 74% 82%, #f67ff5 0px, transparent 50%),
#3b3486;">
<div class="mx-auto max-w-sm rounded-2xl border border-white/20
bg-slate-900/90 p-5 text-slate-50
supports-[backdrop-filter]:bg-slate-900/65
supports-[backdrop-filter]:backdrop-blur-lg
supports-[backdrop-filter]:backdrop-saturate-150">
<h3 class="text-base font-semibold">Weekly report</h3>
<p class="mt-1.5 text-sm text-slate-200">
A dark translucent fill keeps light text readable over every part of the mesh.
</p>
</div>
</section>The panel uses a nearly opaque fill by default and only becomes more transparent when backdrop-filter is supported. backdrop-blur-lg is 16px in Tailwind v4, and Tailwind generates the -webkit-backdrop-filter line for you. A dark fill with light text is the more forgiving choice here because the mesh runs from a dark base (#3b3486) to a bright cyan point (#47e4e0). In the worst case, measured against pure cyan with no blur averaging, #e2e8f0 text over a 55% slate fill comes out at about 4.4:1, just under the 4.5:1 minimum; at 65% it is about 5.8:1. That is why the example uses 65%.
Compare them in context
Place the actual heading, buttons, and content over your preview before deciding. Change one treatment at a time and look at the page at phone width, where a mesh's color points crowd together and a glass panel may cover most of the screen. If a treatment makes an important detail harder to read, remove it rather than compensating with shadows or outlines.