Token Playground


OKLCH Explorer

Drag the sliders to see how each OKLCH channel affects the resulting color. The preview updates live.

oklch(65% 0.20 270)
<div class="playground-controls">
    <div class="playground-slider-group">
        <div class="playground-slider-header">
            <label for="pg-lightness">Lightness</label>
            <output id="pg-lightness-val" class="playground-output">65%</output>
        </div>
        <input type="range" id="pg-lightness" min="0" max="100" value="65" step="1" class="playground-range playground-range--l">
        <div class="playground-slider-meta">
            <span>0% black</span>
            <span>100% white</span>
        </div>
    </div>

    <div class="playground-slider-group">
        <div class="playground-slider-header">
            <label for="pg-chroma">Chroma</label>
            <output id="pg-chroma-val" class="playground-output">0.20</output>
        </div>
        <input type="range" id="pg-chroma" min="0" max="40" value="20" step="1" class="playground-range playground-range--c">
        <div class="playground-slider-meta">
            <span>0.00 gray</span>
            <span>0.40 vivid</span>
        </div>
    </div>

    <div class="playground-slider-group">
        <div class="playground-slider-header">
            <label for="pg-hue">Hue</label>
            <output id="pg-hue-val" class="playground-output">270°</output>
        </div>
        <input type="range" id="pg-hue" min="0" max="360" value="270" step="1" class="playground-range playground-range--h">
        <div class="playground-slider-meta">
            <span>0° red</span>
            <span>90° yellow</span>
            <span>180° cyan</span>
            <span>270° purple</span>
        </div>
    </div>
</div>

Contrast Checker

Pick a foreground and background color to check their WCAG contrast ratio. The tool shows whether your pair passes AA and AAA requirements.

Large Text (18px+)

Normal body text at default size needs higher contrast to remain readable.

AA Normal — AA Large — AAA —
—:1
<div class="playground-contrast-controls">
    <fieldset class="playground-fieldset">
        <legend>Foreground</legend>
        <div class="playground-inline-sliders">
            <div class="playground-mini-slider">
                <label for="cc-fg-l">L</label>
                <input type="range" id="cc-fg-l" min="0" max="100" value="12" step="1" class="playground-range playground-range--l">
                <output id="cc-fg-l-val">12%</output>
            </div>
            <div class="playground-mini-slider">
                <label for="cc-fg-c">C</label>
                <input type="range" id="cc-fg-c" min="0" max="40" value="0" step="1" class="playground-range">
                <output id="cc-fg-c-val">0.00</output>
            </div>
            <div class="playground-mini-slider">
                <label for="cc-fg-h">H</label>
                <input type="range" id="cc-fg-h" min="0" max="360" value="0" step="1" class="playground-range playground-range--h">
                <output id="cc-fg-h-val">0°</output>
            </div>
        </div>
        <div class="playground-color-chip" id="cc-fg-chip"></div>
    </fieldset>

    <fieldset class="playground-fieldset">
        <legend>Background</legend>
        <div class="playground-inline-sliders">
            <div class="playground-mini-slider">
                <label for="cc-bg-l">L</label>
                <input type="range" id="cc-bg-l" min="0" max="100" value="100" step="1" class="playground-range playground-range--l">
                <output id="cc-bg-l-val">100%</output>
            </div>
            <div class="playground-mini-slider">
                <label for="cc-bg-c">C</label>
                <input type="range" id="cc-bg-c" min="0" max="40" value="0" step="1" class="playground-range">
                <output id="cc-bg-c-val">0.00</output>
            </div>
            <div class="playground-mini-slider">
                <label for="cc-bg-h">H</label>
                <input type="range" id="cc-bg-h" min="0" max="360" value="0" step="1" class="playground-range playground-range--h">
                <output id="cc-bg-h-val">0°</output>
            </div>
        </div>
        <div class="playground-color-chip" id="cc-bg-chip"></div>
    </fieldset>
</div>

<div class="playground-contrast-output">
    <button class="playground-copy-btn" id="cc-copy" type="button">
        <i class="ph ph-copy" aria-hidden="true"></i> Copy CSS Pair
    </button>
</div>

Hue Wheel

See the entire hue spectrum at your chosen lightness and chroma. Click any segment to load it into the explorer above.

65%
0.20
Hover or click a segment

Scale Generator

Build a complete lightness scale from a single hue — like Standard’s purple accent or grayscale. Adjust the hue and chroma, and the tool generates 7 harmonized stops.

270°
0.20

Token Presets

Click any preset to load Standard’s actual token values into the explorer.


How OKLCH Works

OKLCH is a perceptually uniform color space with three channels:

Channel Range Meaning
L (Lightness) 0–100% Perceived brightness — 50% always looks “medium” regardless of hue
C (Chroma) 0–~0.4 Color intensity — 0 is pure gray, higher values are more vivid
H (Hue) 0–360° Position on the color wheel — 0° red, 90° yellow, 180° cyan, 270° purple

The key insight: unlike HSL, equal lightness values produce equal perceived brightness. A yellow at L=70% looks as bright as a blue at L=70%. This makes it possible to build harmonious palettes by varying hue while keeping lightness consistent.

Gamut Boundaries

Not all OKLCH values map to displayable sRGB colors. High chroma at extreme lightness values may be out of gamut — the browser will clamp to the nearest displayable color. The explorer above shows a ⚠ indicator when your chosen values are near the gamut edge.

Further Reading

Standard v1.0 • Last built: 3/5/2026, 4:35:01 PM