Use when a gradient between two complementary or distant colours looks muddy in the middle, when a two-stop linear gradient has visible banding on a large surface, when a "mesh" gradient is needed but CSS lacks a native mesh function, when an animated gradient (rotating hue ring, slowly shifting hero) is required without dropping frames, when a conic gradient is wanted for a pie chart or loading ring, when a repeating pattern (stripes, checkerboard, grid) should be expressed in CSS rather than an image, when a gradient on text needs `background-clip: text`, or when a gradient must respect `prefers-reduced-motion`. Prevents the default-sRGB-interpolation muddy-midpoint, the untyped-custom-property gradient that snaps instead of animating, `background-attachment: fixed` parallax (a known compositor disaster on mobile), 30-stop gradients used to "smooth out" what an interpolation-space change would have fixed, conic-gradient pie charts shipped without `role="img"` and an `aria-label`, animated gradients shipped
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Use when a gradient between two complementary or distant colours looks muddy in the middle, when a two-stop linear gradient has visible banding on a large surface, when a "mesh" gradient is needed but CSS lacks a native mesh function, when an animated gradient (rotating hue ring, slowly shifting hero) is required without dropping frames, when a conic gradient is wanted for a pie chart or loading ring, when a repeating pattern (stripes, checkerboard, grid) should be expressed in CSS rather than an image, when a gradient on text needs `background-clip: text`, or when a gradient must respect `prefers-reduced-motion`. Prevents the default-sRGB-interpolation muddy-midpoint, the untyped-custom-property gradient that snaps instead of animating, `background-attachment: fixed` parallax (a known compositor disaster on mobile), 30-stop gradients used to "smooth out" what an interpolation-space change would have fixed, conic-gradient pie charts shipped without `role="img"` and an `aria-label`, animated gradients shipped without a `prefers-reduced-motion` gate, and the assumption that mesh gradients are impossible in CSS (they are emulated by stacking radial gradients). Covers `linear-gradient()`, `radial-gradient()`, `conic-gradient()`, their `repeating-*` variants, the colour-interpolation-method syntax (`linear-gradient(in oklch to right, ...)` and the polar `in oklch longer hue` form for hue-arc control), multi-stop gradients with explicit positions, hard colour stops for stripes (`red 0 50%, blue 50% 100%`), midpoint hints for asymmetric blends (`red, 30%, blue`), layered gradients on a single element (`background: g1, g2, g3;`) for mesh emulation, animated gradients via `@property --gradient-angle` (or any typed custom), gradient-on-text via `background-clip: text` + `color: transparent`, performance considerations (paint-cost of many stops, compositor-friendly opacity vs background-position animation), accessibility for informative gradients (`role="img"` + `aria-label`), and motion-sensitivity gating with `@media (prefers-reduced-motion: reduce)`. Keywords: linear-gradient, radial-gradient, conic-gradient, repeating-linear-gradient, repeating-radial-gradient, repeating-conic-gradient, color-interpolation-method, in oklch, in oklab, in srgb, in lab, in lch, in hsl, in hwb, shorter hue, longer hue, increasing hue, decreasing hue, color hint, midpoint hint, hard color stop, multi-stop, gradient stops, mesh gradient, mesh emulation, layered gradient, stacked radial gradient, gradient angle, gradient animation, animated gradient, @property gradient, background-clip text, gradient on text, repeating gradient, stripes, checkerboard, conic pie chart, loading ring, color wheel, gradient banding, gradient muddy, gradient flat, gradient midpoint gray, animated gradient janky, mesh gradient hard, why does gradient look stripey, why does gradient look muddy, how to make smooth gradient, how to animate gradient, how to make mesh gradient, how to make gradient on text.
license
MIT
compatibility
Designed for Claude Code. Requires Frontend Design evergreen-2026.
metadata
{"author":"OpenAEC-Foundation","version":"1.0"}
Frontend Visual Gradients
This skill defines deterministic rules for shipping CSS gradients (linear-gradient, radial-gradient, conic-gradient, their repeating-* variants), choosing the right colour-interpolation space to avoid muddy midpoints, animating gradients via typed custom properties, emulating mesh gradients with layered radials, and gating animated gradients for motion sensitivity. CSS gradients have been Baseline Widely Available since July 2015; the in <colorspace> interpolation hint (with polar hue arc modifiers) is Baseline 2024.
This skill builds on [[frontend-syntax-css-color-modern]] (oklch, color-mix, relative-colour) and [[frontend-theming-color-palette-oklch]] (palette shades to feed into gradients). Animation primitives come from [[frontend-perf-animation-gpu-containment]] (compositor-only rule + @property).
Without @property registration the custom property is interpolation-opaque and the angle would snap at the end of each cycle (MDN: @property (verified 2026-05-19), Baseline 2024).
CSS has no native mesh-gradient function. Stack multiple radial gradients :
.mesh {
background:
radial-gradient(circle at 20%30%, oklch(0.720.18320) 0%, transparent 50%),
radial-gradient(circle at 80%40%, oklch(0.720.18220) 0%, transparent 55%),
radial-gradient(circle at 50%80%, oklch(0.720.18110) 0%, transparent 60%),
oklch(0.950.02240);
}
Each radial is positioned at a different point, fades to transparent, and stacks over a solid base. The visible result reads as a four-colour mesh blend.
Decision Trees
Decision : linear, radial, or conic?
What shape does the colour transition follow?
A line (across, diagonal, top to bottom)
-> linear-gradient(<dir>, ...)
Add `in oklch` or `in oklab` for clean midpoints.
Outward from a point (spotlight, vignette, glow)
-> radial-gradient([shape] at <pos>, ...)
`circle` for a perfect circle; `ellipse` (default) follows
the box's aspect ratio.
Sweeping around a centre point (pie chart, loading ring, colour wheel)
-> conic-gradient([from <angle>] [at <pos>], ...)
Stops expressed in degrees or percentages.
Multiple radial "blobs" blending together (mesh-style)
-> Stack multiple radial-gradient layers on the same element
with transparency fade-outs and an underlying solid base.
A repeating geometric pattern (stripes, checkerboard, grid)
-> repeating-linear-gradient / repeating-conic-gradient with
hard stops.
Decision : why does my gradient look muddy or banded?
What does the bad result look like?
Midpoint is grey, beige, or dull when the endpoints are vivid
complementary colours (blue -> yellow muddies through olive-grey).
-> Switch interpolation space to oklab or oklch :
linear-gradient(in oklab to right, blue, yellow);
Visible stripes parallel to the gradient direction on a large
surface (banding).
-> Two causes : (a) too few colour stops on a long surface;
(b) sRGB interpolation. Both are mitigated by switching
to `in oklch`. Adding more stops alone WITHOUT changing
interpolation rarely fixes it.
Hue takes the "wrong" path (red to green going via brown instead
of via the bright spectrum).
-> Use a polar space + hue arc :
linear-gradient(in oklch longer hue, red, green);
Hard-edge appears where the author wanted a smooth blend.
-> A stop pair sharing the same position creates a hard edge.
Use distinct positions (red 0%, blue 100%) instead of
(red 50%, blue 50%).
Decision : static or animated gradient?
Does the gradient change over time or in response to interaction?
No, it is static.
-> Plain background-image rule. Pick the right interpolation
space and ship it. Set on background-image; never on
background-color (gradients are images).
Yes, the gradient rotates (angle changes).
-> Register --grad-angle with @property as <angle>; declare
the gradient with var(--grad-angle); animate the custom
property. Gate with prefers-reduced-motion.
Yes, the gradient shifts colour (tint shift, hue drift).
-> Register the colour custom property with @property as <color>;
animate the custom property. Gate with prefers-reduced-motion.
Yes, the gradient "moves" across the surface (animated band).
-> Use background-size > 100% and animate background-position.
NOTE : background-position animation triggers paint per frame
on the entire painted region; budget paint cost OR replace
with a transformed overlay and animate transform.
Decision : mesh approximation strategy?
How complex is the target mesh?
2-4 blobs, soft edges, no sharp boundaries.
-> Stack 2-4 radial-gradient layers on one element, each fading
to transparent over a solid base colour. See Pattern 4 in
examples.md.
Many irregular blobs, organic shapes.
-> SVG <feGaussianBlur> on randomised <circle> elements is the
right tool; reference the SVG as a CSS background-image
(url(#mesh-filter)) or render inline. Out of scope for this
skill; see Cross-references.
Animated mesh (blobs drift slowly).
-> Two compositor-friendly options :
1. Animate transforms on absolutely-positioned blurred divs
layered over a base (movement is on transform, not paint).
2. Animate a typed custom property used inside the radial
gradient (e.g. --blob1-x : <length>). Costs paint per
frame; budget accordingly.
Patterns
Pattern 1 : smooth two-colour hero with in oklch
.hero { background: linear-gradient(in oklch to right, oklch(0.650.18250), oklch(0.720.20320)); }
Vivid endpoints, no muddy midpoint, no banding on a 1920px-wide surface.