CSS gradients went out of fashion for a few years — we were all going flat and minimal, everything white and grey. Then dark mode arrived, glassmorphism came back, and suddenly designers were layering mesh gradients, aurora effects, and noise textures on everything. Gradients are having their moment, and modern CSS is genuinely up to the task.
You can do things in two lines of CSS that once required a Photoshop export. Browser support is excellent across all three gradient types. Here's a complete walkthrough of every gradient function, the syntax details that actually matter, and patterns worth stealing for your next project.
linear-gradient: Syntax Deep Dive
linear-gradient() is the most common gradient function. It transitions colours along a straight line in a direction you specify. The first argument is the direction; everything after is a list of colour stops.
/* Direction keywords */ background: linear-gradient(to right, #1a5c3a, #4CC87E); background: linear-gradient(to bottom right, #0f172a, #4CC87E); /* Degree values — 0deg is upward, increases clockwise */ background: linear-gradient(90deg, #1a5c3a, #4CC87E); /* left to right */ background: linear-gradient(180deg, #1a5c3a, #4CC87E); /* top to bottom */ background: linear-gradient(135deg, #0f172a, #1a5c3a, #4CC87E); /* diagonal */
The angle system follows the CSS specification: 0deg points upward (equivalent to to top), and angles increase clockwise. So 90deg is to right, 180deg is to bottom, and 270deg is to left. You can use any angle including negative values and values greater than 360 degrees.
Colour stops can be positioned precisely using lengths or percentages. Without explicit positions, stops are distributed evenly. Explicit positioning gives you precise control over where transitions happen and their speed:
/* Abrupt transition at exactly 50% */ background: linear-gradient(to right, #000 50%, #fff 50%); /* Slow fade from dark, rapid brightening at the end */ background: linear-gradient(to right, #F8FAF9 0%, #F8FAF9 60%, #4CC87E 100%); /* Hard stop using duplicate position */ background: linear-gradient(135deg, #0f172a 0%, #1a5c3a 40%, #1a5c3a 60%, /* flat band in the middle */ #4CC87E 100% );
radial-gradient: Circles, Ellipses, and Glow Effects
radial-gradient() radiates outward from a centre point. The first argument defines the shape and size; the at keyword sets the centre position.
/* Circle, centred */ background: radial-gradient(circle at center, #4CC87E33, transparent 70%); /* Ellipse, positioned at top centre — common for hero glow effects */ background: radial-gradient(ellipse 80% 50% at 50% 0%, #1a5c3a44, transparent); /* Precise circle size with farthest-corner */ background: radial-gradient(circle farthest-corner at 30% 70%, #4CC87E, #0f172a);
The shape parameter can be circle (always circular) or ellipse (default, stretches to the element's aspect ratio). The size keywords control where the gradient ends: closest-side, farthest-side, closest-corner, and farthest-corner. You can also specify explicit dimensions as lengths or percentages.
Radial gradients are the primary tool for "glow" effects in dark UIs. The pattern is a radial gradient from a semi-transparent brand colour to transparent, positioned at the top or corner of an element. The soft falloff gives a natural-looking backlight effect that flat colours cannot replicate.
conic-gradient: Pie Charts, Spinners, and Colour Wheels
conic-gradient() is the newest of the three gradient types and the most underused. Instead of radiating outward from a point, it transitions colours around a centre point — like a clock, a pie chart, or a colour wheel. Browser support has been solid since 2021 (Chrome 69+, Firefox 83+, Safari 12.1+).
/* Full colour wheel */ background: conic-gradient(from 0deg, hsl(0 100% 50%), hsl(360 100% 50%)); /* Pie chart segments */ background: conic-gradient( #4CC87E 0% 35%, /* 35% green */ #1a5c3a 35% 65%, /* 30% dark green */ #0f172a 65% 100% /* 35% near-black */ ); /* Angular gradient from top */ background: conic-gradient(from 90deg at 50% 50%, #ff6b6b, #ffd93d, #6bcb77, #4d96ff, #ff6b6b); /* CSS spinner using animation */ background: conic-gradient(from 0deg, transparent 0%, #4CC87E 30%, transparent 31%); /* Pair with: animation: spin 1s linear infinite; */
Conic gradients can replace JavaScript-drawn canvas pie charts for simple data visualisations. They can also create checkerboard and repeating patterns when combined with repeating-conic-gradient(). The repeating variants exist for all three gradient types and work just like the base versions but tile the stop pattern.
Multiple Gradient Layers and Mesh Gradients
The background property accepts multiple comma-separated values. Each value is a separate layer, rendered from front to back. This is how mesh gradients are built in CSS — not a single gradient function, but a composition of multiple radial gradients at different positions, each covering a different "node" of the mesh.
/* Mesh gradient: four radial gradient nodes */ background: radial-gradient(ellipse 60% 50% at 20% 30%, rgba(76, 200, 126, 0.4), transparent 60%), radial-gradient(ellipse 50% 60% at 80% 20%, rgba(26, 92, 58, 0.5), transparent 55%), radial-gradient(ellipse 70% 40% at 60% 80%, rgba(76, 200, 126, 0.3), transparent 65%), radial-gradient(ellipse 40% 70% at 10% 70%, rgba(15, 23, 42, 0.8), transparent 50%), #F8FAF9; /* solid base colour */
The key to a convincing mesh gradient is using semi-transparent colours that blend naturally, varying the ellipse proportions and positions, and ensuring the base colour shows through between nodes. Most of the attractive "aurora" and "mesh" backgrounds you see in modern SaaS UIs are 4-6 layered radial gradients over a dark solid.
Gradient Text Effect
The gradient text technique clips a background gradient to the text shape using background-clip: text. It is widely supported and produces sharp, resolution-independent results:
h1 {
background: linear-gradient(135deg, #4CC87E, #a8f0c6, #4CC87E);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
/* Fallback for environments without support: */
color: #4CC87E;
}The -webkit- prefix is still required for background-clip on some Safari versions. The color declaration serves as a fallback in the rare case that neither prefixed nor unprefixed background-clip: text is supported. Note that the element must have a non-transparent background for the clip to be visible — this technique does not work on elements with background: none.
Gradient Borders with border-image
Creating gradient borders with standard CSS requires a workaround because border-color does not accept gradient values. The two main techniques are border-image and the pseudo-element approach with background-clip.
/* border-image approach — simple but loses border-radius */
.card {
border: 1px solid transparent;
border-image: linear-gradient(135deg, #4CC87E, #1a5c3a) 1;
}
/* Pseudo-element approach — preserves border-radius */
.card {
position: relative;
border-radius: 12px;
background: #0f172a; /* must match page background */
}
.card::before {
content: "";
position: absolute;
inset: -1px;
border-radius: 13px; /* 1px larger than parent */
background: linear-gradient(135deg, #4CC87E, #1a5c3a);
z-index: -1;
}The border-image approach is simpler but cannot have rounded corners — border-radius is ignored on elements with border-image. The pseudo-element approach requires knowing the background colour, but supports border-radius and is the correct solution for card UIs.
Animating Gradients
CSS gradients themselves cannot be directly animated with transition or @keyframes — they are treated as images, not interpolatable values. The workaround is to animate a property that indirectly changes the gradient's appearance, usually background-position on an oversized gradient:
/* Animated gradient using background-position */
.animated-bg {
background: linear-gradient(270deg, #4CC87E, #1a5c3a, #0f172a, #4CC87E);
background-size: 400% 400%;
animation: gradientShift 8s ease infinite;
}
@keyframes gradientShift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
/* CSS Houdini @property allows true gradient animation in Chrome/Edge */
@property --gradient-angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
.houdini-animated {
background: linear-gradient(var(--gradient-angle), #4CC87E, #0f172a);
animation: rotate 4s linear infinite;
}
@keyframes rotate {
to { --gradient-angle: 360deg; }
}The Houdini @property approach enables true gradient interpolation in Chromium-based browsers and Safari 15.4+. Firefox support for @property arrived in version 128 (2024). For the background-position trick, performance is excellent because it only triggers compositing, not layout or paint.
CSS Custom Properties with Gradients
CSS custom properties (variables) compose well with gradients, enabling dynamic theming and reusable gradient systems:
:root {
--brand: #4CC87E;
--brand-dark: #1a5c3a;
--bg-deep: #F8FAF9;
--gradient-brand: linear-gradient(135deg, var(--brand-dark), var(--brand));
--gradient-glow: radial-gradient(ellipse 70% 40% at 50% 0%,
rgba(76, 200, 126, 0.25), transparent);
}
/* Use the variables */
.button { background: var(--gradient-brand); }
.hero { background: var(--gradient-glow), var(--bg-deep); }Note that you cannot put only part of a gradient function in a custom property and interpolate it into the middle of a function call — the entire gradient value must be in the variable, or the colour stop values must be in separate variables. This is a current limitation of CSS variable parsing.
Performance Considerations and Browser Support
CSS gradients are painted by the GPU and are generally very fast — faster than an equivalent raster image, which requires a network request and decode. The performance concern with gradients is animation: rapidly changing gradient values that force repaint on every frame. The background-position animation pattern avoids this because it only triggers compositing. Avoid animating background-size, inline gradient functions with changing stop values, or any approach that causes layout recalculation.
Browser support for all three gradient types (linear-gradient, radial-gradient, and conic-gradient) is above 96% global usage as of 2024. The repeating- variants have the same support. The main edge case is very old WebView-based Android apps; if you need to support those, test your specific gradient usage carefully.
Writing complex multi-stop gradients by hand is tedious — a visual editor where you can drag colour stops and see the result in real time dramatically speeds up the process. Tanvrit's CSS Gradient Generator builds linear, radial, and conic gradients visually and copies clean CSS to your clipboard — no account required, no data stored. Open the Gradient Generator →