Skip to content

All tools (41)

JSON 6
Time & Date 4
Encoding & Decoding 4
Generators 3
Text & Data 4
Logs & Debugging 1
Config & Infra 3
Security & Hashing 4
Color & Design 5
Numbers & Bits 3
Web & Markup 4

Nothing leaves the cave.

Nothing you paste ever leaves your device. There is no server to send it to.

How you can check →
DevToolsCave

    This tool runs entirely in your browser. Nothing you paste is uploaded.

    How you can check →

    OKLCH Gradient Generator

    Color & Design

    Author a CSS gradient in OKLCH and see the lightness curve, the chroma against the gamut ceiling, the hue arc and a derived sRGB fallback — the pictures no other gradient tool draws.

    Kind

    Stop 1 of 2

    OKLCH plane at hue 30.00° Lightness left to right, chroma bottom to top, at a fixed hue of 30.00°. The shaded regions show how much chroma sRGB and Display P3 can hold at each lightness.
    L 0 Lightness L 1
    %

    Analysis

    Lightness, chroma and banding along the gradient Lightness is flat at 0.72 across the whole gradient. The chroma curve crosses above the gamut ceiling for 20.3% of the gradient's length.
    0% Distance along the gradient line 100%

    Lightness · Chroma vs. ceiling (filled region is what the target gamut can hold) · Banding (predicted, 8-bit non-dithered) with a 10× exaggerated strip below it.

    Sampled values
    Position L C H
    0.0% 0.7200 0.1500 30.00
    3.1% 0.7200 0.1500 33.45
    6.3% 0.7200 0.1500 36.90
    9.4% 0.7200 0.1500 40.35
    12.5% 0.7200 0.1500 43.80
    15.7% 0.7200 0.1500 47.25
    18.8% 0.7200 0.1500 50.71
    22.0% 0.7200 0.1500 54.16
    25.1% 0.7200 0.1500 57.61
    28.2% 0.7200 0.1500 61.06
    31.4% 0.7200 0.1500 64.51
    34.5% 0.7200 0.1500 67.96
    37.6% 0.7200 0.1500 71.41
    40.8% 0.7200 0.1500 74.86
    43.9% 0.7200 0.1500 78.31
    47.1% 0.7200 0.1500 81.76
    50.2% 0.7200 0.1500 85.22
    53.3% 0.7200 0.1500 88.67
    56.5% 0.7200 0.1500 92.12
    59.6% 0.7200 0.1500 95.57
    62.7% 0.7200 0.1500 99.02
    65.9% 0.7200 0.1500 102.47
    69.0% 0.7200 0.1500 105.92
    72.2% 0.7200 0.1500 109.37
    75.3% 0.7200 0.1500 112.82
    78.4% 0.7200 0.1500 116.27
    81.6% 0.7200 0.1500 119.73
    84.7% 0.7200 0.1500 123.18
    87.8% 0.7200 0.1500 126.63
    91.0% 0.7200 0.1500 130.08
    94.1% 0.7200 0.1500 133.53
    97.3% 0.7200 0.1500 136.98
    Hue arc — shorter Four possible paths from 30.0 to 140.0 degrees of hue; the shorter arc is currently selected.

    Click an arc to switch the hue-interpolation method

    Presets
    Import from CSS
    Modern CSS

    Why a gradient that looks fine in numbers can still disappoint on screen

    OKLCH describes a color as lightness, chroma and hue, and a gradient walks a straight line through that space between your stops. The problem is that sRGB — the gamut almost every screen still has to answer to — isn't a cube in OKLCH terms. Its ceiling, the maximum chroma it can hold, rises and falls with both lightness and hue. A gradient can start and end safely inside that ceiling and still cross a stretch in the middle where the ceiling dips below the chroma the straight line calls for. The browser has no choice but to gamut-map that stretch to something else — usually a less saturated color at the same lightness and hue — and nothing about the two endpoints you typed would have warned you.

    What the charts on this page are for

    The lightness and chroma curves plot exactly what the CSS renders, sampled along the gradient's own axis (distance along the line for a linear gradient, the radius for a radial one, the angle for a conic one). The chroma curve is drawn against a filled ceiling — the largest chroma the target gamut can hold at that exact lightness and hue, computed by a binary search rather than read from a table. Wherever the curve pokes above the fill, that stretch is out of gamut, and the verdict line above the gradient states the percentage, the range and the peak amount by which it overshoots.

    The sRGB gamut ceiling, by hue

    "Ceiling" is a specific number: the largest OKLCH chroma a gamut can hold at a given lightness and hue before the color falls outside it. It isn't flat — it rises and falls with hue at any fixed lightness, which is the whole reason a straight-line gradient can leave the gamut in the middle even when both ends are safely inside it. The table below is generated by this page's own gamut-ceiling search at L = 0.5, the same binary search the chroma chart runs live, not a number copied from anywhere else.

    Hue Max chroma, sRGB Max chroma, Display-P3
    0.2027 0.2281
    30° 0.2004 0.2240
    60° 0.1172 0.1340
    90° 0.1021 0.1179
    120° 0.1187 0.1383
    150° 0.1377 0.1921
    180° 0.0907 0.1230
    210° 0.0865 0.1153
    240° 0.1146 0.1496
    270° 0.2813 0.3003
    300° 0.2670 0.2779
    330° 0.2279 0.2497

    Read a row as: at lightness 0.5, sRGB cannot hold more chroma than this at this hue — ask for more and the browser has to gamut-map it to something else. Display-P3's column is consistently higher, which is the numeric version of "P3 screens can show more vivid color at the same lightness." This is also why a fixed #chroma value that looks vivid at one hue can look washed out or clipped at another — the ceiling it's fighting isn't the same number.

    Why an OKLCH gradient can sometimes look worse than an sRGB one

    The case for OKLCH is usually the one this page makes with its own default: a straight line in a perceptually uniform space skips the muddy grey dip that a straight line in sRGB produces between complementary hues. But the reverse can happen too, and it's worth stating plainly rather than only ever making the favorable case. If both of your stops already sit close to the sRGB hull, the straight line sRGB draws between them can stay inside the gamut the whole way, while the straight line OKLCH draws between the same two colors can bow out through a region of higher chroma and clip. OKLCH's line is straighter in a perceptual sense, not in an sRGB-shaped one — and a gamut that isn't sRGB-shaped is exactly what makes the two lines diverge. Toggle "Compare: sRGB interpolation of the same stops" below the charts to see whether that's happening to your gradient specifically, rather than assuming either space always wins.

    Three different defaults, and the one this page always states

    A bare CSS gradient with no interpolation hint doesn't default to sRGB the way many people assume — it defaults to Oklab, per CSS Color 4 §13.2, and sRGB is only what you get as a web-compatibility exception when every single stop is a legacy color syntax (a hex code, rgb(), hsl() or a named color). Write linear-gradient(oklch(0.7 0.1 30), oklch(0.7 0.1 200)) with no in keyword and you already have an Oklab gradient, not an sRGB one. Tailwind CSS v4's gradient utilities default to Oklab as well, and take /oklch, /srgb, /hsl and the four hue-arc keywords as modifiers — but only on the class-name form; an arbitrary value like bg-linear-[120deg]/oklch silently produces no CSS at all, and has to be written bg-linear-[120deg_in_oklch] instead. This page never relies on any of those three defaults — every export states in oklch explicitly, which is the only way the CSS says what it means regardless of which stops it contains.

    Browser support, with the dates that matter

    The in <color-space> interpolation-method syntax used throughout this page shipped later than the oklch() color function itself in every major engine — which is the actual cause behind "the color works but the gradient looks wrong" reports. Support lands per space, not all at once: Chrome shipped in oklch in Chrome 111 (7 March 2023), Safari in Safari 16.2 (13 December 2022) and Firefox in Firefox 127 (11 June 2024) — a full year after Firefox had already shipped the color function it interpolates. in display-p3 and in rec2020 arrived later still in Chromium, so support is feature-detected per space here rather than printed as one version number for all ten interpolation spaces. When your browser can't render the hint, the live preview swaps to the pre-sampled fallback below and says so — the CSS output itself doesn't change, because it's still correct for a browser that supports it.

    The derived sRGB fallback, and how the number is earned

    Engines without the in oklch interpolation syntax, and SVG (which has no OKLCH gradient primitive at all — SVG 1.1's <linearGradient> only ever interpolates in sRGB), need a pre-sampled stop list instead of the live interpolation hint. Rather than picking a stop count in advance the way every other gradient tool in the field does — 12, or 8, or a "precision" slider with no stated consequence — this page samples the true OKLCH path at 512 or more points, then searches for the smallest stop count whose worst-case color difference (ΔEOK, the OKLab-space color-difference metric) from that true path stays under a threshold set well inside the ~2.0 just-noticeable-difference mark. The Fallback tab prints the count it found and the measured error side by side — for example 42 stops · max error 0.31 ΔEOK — so the number is auditable rather than asserted.

    Doing this in code

    Everything on this page also exists as a library if you'd rather compute it in a build step. Each option makes its own choice about gamut mapping, which is worth knowing before you compare numbers between them:

    // culori — clips to the destination gamut by default; use displayable()
    // or a mapping mode explicitly if you need CSS Color 4's chroma-reduction behavior.
    import { oklch, formatCss, displayable } from "culori";
    const c = oklch("oklch(0.72 0.19 250)");
    console.log(displayable(c)); // false if it's outside sRGB
    
    // colorjs.io — implements the CSS Color 4 gamut-mapping algorithm this page also
    // follows (reduce chroma at fixed L and H, not per-channel clipping).
    import Color from "colorjs.io";
    const inGamut = new Color("oklch(72% 0.19 250)").inGamut("srgb");
    
    // postcss-easing-gradients — eased (non-linear) gradient stops as a PostCSS plugin,
    // in sRGB rather than OKLCH; useful once you've picked stops here and want easing too.

    Common use cases

    • Checking whether a brand gradient stays inside sRGB before shipping it
    • Picking the right hue arc for a sweep that should go the long way around the wheel
    • Getting a Tailwind v4 utility class with the correct interpolation modifier
    • Producing a measured, not guessed, sRGB fallback stop list for older browsers or SVG
    • Understanding why a wide-hue gradient looks flat in the middle in a way a narrow one doesn't

    Frequently asked questions

    Why does my OKLCH gradient look flat or washed out in the middle?
    OKLCH's lightness and chroma travel in a straight line between your two stops, but the gamut that has to hold that line isn't a straight-sided shape — its ceiling dips and rises with hue. A gradient can start and end inside sRGB and still cross a stretch in the middle where the ceiling is lower than the chroma the straight line asks for, and the browser has to gamut-map that stretch to something else. This page draws that ceiling under the chroma curve and states the out-of-gamut percentage, so the dip is a picture instead of a mystery.
    What does an out-of-gamut percentage mean, and what will the browser actually paint?
    It's the share of the gradient's length whose OKLCH chroma, at that exact lightness and hue, exceeds what the target gamut (sRGB by default) can hold. Per CSS Color 4, the browser answers this by reducing chroma at fixed lightness and hue until the color fits — never by clipping channels, which would shift the hue. We can't read back what a given engine actually painted (canvas can't rasterise a live CSS gradient), so our chart is labeled as the spec's answer, shown beside the browser's own live preview rather than instead of it.
    Should I use "in oklch" or "in oklab"? Tailwind's default is oklab.
    Bare CSS with no interpolation hint at all defaults to Oklab (not sRGB) once every stop is a modern color — the sRGB default only applies when every stop is a legacy color like a hex or rgb(). Tailwind v4's gradient utilities default to oklab too, with /oklch and the hue-arc keywords available as modifiers. This page always emits an explicit "in oklch" hint, which is what makes the CSS say exactly what it means instead of relying on either default.
    How many stops does an sRGB fallback need, and how do I know it's enough?
    The Fallback tab derives the smallest stop count whose worst-case color difference from the true OKLCH path stays under a threshold well inside the ~2.0 just-noticeable-difference mark, and prints both the count and the measured error together — never a fixed number picked in advance the way most gradient tools do it.
    Why does "longer hue" go the wrong way round?
    Hue is an angle, so there are always two ways from one hue to another: the short way and the long way. "Shorter" and "longer" pick whichever arc is under or over 180 degrees; "increasing" and "decreasing" always walk one numeric direction regardless of which is shorter. The hue-arc select controls which of the four your gradient actually uses.
    Does this work in Firefox?
    The "in oklch" interpolation-method syntax used here shipped in Chrome 111 (March 2023), Safari 16.2 (December 2022) and Firefox 127 (June 2024) — later than the oklch() color function itself in every one of those engines, which is the usual source of "it works in my Firefox but the gradient looks different" reports. When your browser doesn't support it, the live preview swaps to the pre-sampled fallback automatically and says so.
    Is my gradient sent anywhere?
    No — every stop, every chart and every export is computed in your browser. Nothing you enter here is logged, persisted or transmitted.