CSS gradients are one of the most practical tools in a front-end developer's kit. They replace image files for backgrounds, buttons, overlays, and text effects, loading instantly with zero extra HTTP requests. They scale to any resolution without blurring. And with a CSS gradient generator, you can preview them visually and copy the code in seconds without guessing at hex values or angle syntax.
This guide covers all three gradient types in depth, including 10 real-world copy-paste patterns, a step-by-step animated gradient tutorial, and the performance rules that prevent gradients from slowing your page down. If you have only used simple two-colour fades, there is a lot more here worth knowing.
Linear gradients: the foundation
A linear gradient transitions between colours along a straight line. The direction can be a keyword (to right, to bottom, to bottom right) or a degree angle (45deg, 135deg, 270deg). The default direction is to bottom, which fades top to bottom.
You can add as many colour stops as you need, and each stop can have an explicit percentage position. Without explicit positions, the browser distributes stops evenly: three stops at 0%, 50%, and 100%. With explicit positions you get precise control over where a colour starts, holds, and transitions. A hard stop (two colours at the same position) creates a sharp edge instead of a fade: useful for striped patterns and segmented designs.
/* Syntax breakdown */
background: linear-gradient(direction, color-stop-1, color-stop-2, ...);
/* Diagonal, two colours */
background: linear-gradient(135deg, #667eea, #764ba2);
/* Three-stop: blue, white midpoint, purple */
background: linear-gradient(to right, #667eea, #ffffff 50%, #764ba2);
/* Hard stop: sharp red-to-blue split at 50% */
background: linear-gradient(to right, #ef4444 50%, #3b82f6 50%);Radial gradients: spotlight and glow effects
A radial gradient radiates outward from a centre point. The default shape is an ellipse that fits the element's box, but you can specify circle for a perfectly round spread. The starting point defaults to the centre but can be positioned anywhere using the at keyword: radial-gradient(circle at 20% 80%, ...) places the origin in the lower-left area.
The size of the gradient can be controlled with keywords: closest-side, farthest-side, closest-corner, and farthest-corner. The default is farthest-corner, which means the gradient reaches all four corners. Radial gradients are the right tool for spotlight effects on dark backgrounds, glow effects around buttons, vignettes on images, and circular progress indicators.
/* Centred glow on a dark card */
background: radial-gradient(circle at 50% 30%, rgba(99,102,241,0.4), transparent 70%);
/* Vignette overlay on an image */
background: radial-gradient(ellipse at center, transparent 50%, rgba(0,0,0,0.7) 100%);
/* Spotlight from the top-left */
background: radial-gradient(circle at 10% 10%, rgba(255,255,255,0.15), transparent 60%);Conic gradients: pie charts and colour wheels
A conic gradient rotates colour stops around a centre point, like the hands of a clock sweeping around a dial. The syntax mirrors linear gradients but uses degrees instead of percentages as positions. The default start angle is 0deg (top), and rotation goes clockwise.
Conic gradients are the right tool for pie charts (pair with clip-path or border-radius: 50% to make a circle), colour wheels, progress rings, and segmented backgrounds. A repeating-conic-gradient creates checkerboard and starburst patterns that would otherwise require SVG or images.
/* Two-slice pie chart: 40% blue, 60% purple */
background: conic-gradient(#3b82f6 0deg 144deg, #7c3aed 144deg 360deg);
/* Full colour wheel */
background: conic-gradient(
hsl(0,100%,50%),
hsl(60,100%,50%),
hsl(120,100%,50%),
hsl(180,100%,50%),
hsl(240,100%,50%),
hsl(300,100%,50%),
hsl(360,100%,50%)
);
/* Checkerboard via repeating-conic-gradient */
background: repeating-conic-gradient(#e2e8f0 0deg 90deg, #94a3b8 90deg 180deg);
background-size: 40px 40px;10 copy-paste gradient examples
These patterns cover the most common real-world use cases. Each one is production-ready: copy, paste, and adjust the colours to match your design. If you want to tweak the values interactively, open the CSS gradient generator at the top of this page.
1. Hero section background
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);2. Subtle card background (dark mode)
background: linear-gradient(145deg, #1e293b 0%, #0f172a 100%);3. Sunrise (warm multi-stop)
background: linear-gradient(to bottom, #fbbf24 0%, #f97316 40%, #dc2626 100%);4. Text gradient (gradient clipped to text)
background: linear-gradient(to right, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
color: transparent;5. Button hover glow
.btn {
background: linear-gradient(135deg, #6366f1, #8b5cf6);
transition: box-shadow 0.2s ease;
}
.btn:hover {
box-shadow: 0 0 24px rgba(99, 102, 241, 0.5);
}6. Gradient border (no border-image needed)
.gradient-border {
background:
linear-gradient(#0f172a, #0f172a) padding-box,
linear-gradient(135deg, #667eea, #764ba2) border-box;
border: 2px solid transparent;
border-radius: 12px;
}7. Radial card glow (top centre)
background: radial-gradient(ellipse at 50% -20%, rgba(99,102,241,0.35) 0%, transparent 60%),
#1e293b;8. Skeleton loading shimmer (static, no animation)
background: linear-gradient(
90deg,
#1e293b 25%,
#334155 50%,
#1e293b 75%
);
background-size: 200% 100%;9. Striped divider
background: repeating-linear-gradient(
45deg,
#6366f1,
#6366f1 4px,
transparent 4px,
transparent 20px
);
height: 4px;10. Conic progress ring
/* Shows 65% completion */
.ring {
background: conic-gradient(#6366f1 0deg 234deg, #1e293b 234deg 360deg);
border-radius: 50%;
width: 120px;
height: 120px;
}
.ring-inner {
/* Cut out the centre to make it a ring */
background: #0f172a;
border-radius: 50%;
width: 88px;
height: 88px;
margin: 16px;
}Animated gradients: a step-by-step tutorial
CSS cannot animate gradient colour stops directly: the gradient itself is not a CSS property that the browser can interpolate between two values. The workaround used everywhere is to animate the background-position on a gradient that is larger than its container. This creates smooth motion without JavaScript.
The technique works like this: you define a gradient at 200% or 400% width (or height), then use a CSS keyframe animation to slide the background-position from one end to the other. Because the gradient is bigger than the visible area, moving it creates the appearance of colour shifting across the element.
Animated hero gradient
@keyframes gradientShift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.hero {
background: linear-gradient(
270deg,
#667eea,
#764ba2,
#f97316,
#06b6d4
);
background-size: 400% 400%;
animation: gradientShift 8s ease infinite;
}The background-size: 400% 400% makes the gradient four times the container's size. The animation moves the visible window across it. Slower durations (8 to 12 seconds) feel ambient and professional. Faster durations (2 to 4 seconds) feel energetic but can become distracting. Match the pace to the mood of the page.
Animated shimmer for loading skeletons
Skeleton loading screens use an animated shimmer to show that content is on its way. The classic implementation uses background-position animation on a linear gradient:
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
.skeleton {
background: linear-gradient(
90deg,
#1e293b 25%,
#334155 50%,
#1e293b 75%
);
background-size: 200% 100%;
animation: shimmer 1.5s infinite linear;
border-radius: 6px;
}The gradient has three stops: dark, lighter, dark. As the animation slides it left to right, the lighter midpoint sweeps across the element, creating a convincing shimmer. Using linear timing (not ease-in-out) keeps the sweep speed constant, which looks more natural than a shimmer that accelerates and decelerates.
Animated gradient border
@keyframes borderSpin {
0% { --angle: 0deg; }
100% { --angle: 360deg; }
}
@property --angle {
syntax: '<angle>';
initial-value: 0deg;
inherits: false;
}
.animated-border {
background:
linear-gradient(#0f172a, #0f172a) padding-box,
conic-gradient(from var(--angle), #667eea, #764ba2, #f97316, #667eea) border-box;
border: 2px solid transparent;
border-radius: 12px;
animation: borderSpin 3s linear infinite;
}This pattern uses the @property rule to register a custom CSS property with a type, which allows the browser to interpolate it in animations. Without @property, CSS cannot animate a custom variable used inside a gradient. The result is a rotating rainbow border with no JavaScript.
@property is supported in Chrome 85+, Edge 85+, and Safari 16.4+. Firefox 128+ also supports it. For older browsers, provide a static gradient border as a fallback.
Gradient performance tips
Gradients render entirely on the GPU and cost almost nothing at rest: a single static gradient background is essentially free. The performance considerations arise when you animate them incorrectly or stack too many layers on too many elements.
Animate transform and opacity, not background-position
The background-position animation technique is widely used, but it triggers a paint step on every frame because the browser has to redraw the background content. On most modern devices this is invisible, but on mobile or low-powered hardware it can cause dropped frames. The higher-performance alternative is to use a pseudo-element for the gradient and animate transform: translateX on the pseudo-element instead. Transform animations run entirely on the GPU compositing layer without triggering a repaint.
/* GPU-composited shimmer: no repaint on each frame */
.skeleton {
position: relative;
overflow: hidden;
background: #1e293b;
border-radius: 6px;
}
.skeleton::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(
90deg,
transparent 0%,
rgba(255,255,255,0.06) 50%,
transparent 100%
);
transform: translateX(-100%);
animation: shimmerGPU 1.5s infinite linear;
}
@keyframes shimmerGPU {
to { transform: translateX(100%); }
}Limit stacked gradient layers
The CSS background property accepts multiple layers separated by commas. Each layer is rendered independently. Stacking two or three gradient layers is fine. Stacking eight or ten layers on dozens of elements on the same page adds up: the browser must composite all those layers on every frame. Keep stacked gradient layers to three or fewer per element. If a design calls for more, flatten the effect into a single gradient or use an SVG background instead.
Use will-change sparingly
Adding will-change: background to an animated element tells the browser to promote it to its own compositing layer. This can improve animation smoothness but costs GPU memory. Apply it only to elements that are actually animating, and remove it once the animation completes (using JavaScript event listeners). Applying will-change to everything is a common mistake that consumes memory with no benefit for static elements.
Prefer background-size over repeating gradients for patterns
A repeating-linear-gradient that tiles every 20 pixels over a large element requires the browser to calculate many more colour stops than a non-repeating gradient covering the same area at a larger background-size. For tiling patterns, defining a single tile with background-size and letting the browser handle repetition is often faster than using a repeating gradient function directly.
Combining gradients: stacking layers
The CSS background property accepts multiple values separated by commas. Each value is rendered as a layer, with the first value on top. This lets you combine gradient types, set transparency, and add a fallback solid colour at the bottom of the stack.
/* Radial glow on top of a diagonal gradient */
background:
radial-gradient(circle at 70% 20%, rgba(99,102,241,0.3), transparent 50%),
linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
/* Grid overlay on a solid colour */
background:
linear-gradient(rgba(99,102,241,0.07) 1px, transparent 1px),
linear-gradient(90deg, rgba(99,102,241,0.07) 1px, transparent 1px),
#0f172a;
background-size: 100% 100%, 100% 100%, auto;
background-size: auto, 40px 40px, auto;Browser support
Linear and radial gradients work in every browser in use today, including IE10. Conic gradients are supported in Chrome 69+, Firefox 83+, and Safari 12.1+: covering more than 96% of global browser usage as of mid-2026. The @property rule for animated gradient variables requires Chrome 85+, Safari 16.4+, or Firefox 128+: if you need broader coverage, fall back to a static gradient border or use the background-position animation approach instead.
For the rare environment where conic gradients are not supported, provide a solid-colour fallback before the gradient declaration. The browser ignores declarations it cannot parse and uses the last one it understood:
/* Solid colour fallback first, conic on top */
background: #3b82f6;
background: conic-gradient(#3b82f6 0deg 144deg, #7c3aed 144deg 360deg);Using a CSS gradient generator
Writing gradient CSS by hand works, but adjusting colours and stops without a visual preview is slow. A CSS gradient generator lets you drag stops, pick colours from a colour picker, switch gradient type with a click, and copy the finished CSS. This is especially useful for radial and conic gradients where the angle and position parameters are harder to reason about in text.
The gradient generator at AlteredIdea supports all three gradient types, lets you preview against a light or dark background, and generates clean CSS with no vendor prefixes beyond the minimum needed for text gradients. All processing happens in your browser: nothing is sent to a server.
AlteredIdea's CSS Gradient Generator lets you build linear, radial, and conic gradients visually, add and drag colour stops, adjust angles, and copy the finished CSS with one click. Free, browser-based, no account needed.