The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
sRGB hexadecimal.notice { color: #1d4ed8; }View examples
Alpha channel.overlay { background: rgb(15 23 42 / 60%); }View examples
Perceptual color.brand { color: oklch(55% 0.2 260); }View examples
Mix colors.soft { background: color-mix(in oklab, var(--brand) 15%, white); }View examples
Relative color.hover { color: oklch(from var(--brand) calc(l - .08) c h); }View examples
Declare supported schemes:root { color-scheme: light dark; }View examples
Scheme-dependent valuebody { color: light-dark(#172033, #e6edf7); }View examples
Query dark preference@media (prefers-color-scheme: dark) { :root { --surface: #0f172a; }; }View examples
Style control accentform { accent-color: #2563eb; }View examples
Adapt forced colors@media (forced-colors: active) { .icon { color: ButtonText; }; }View examples
Reuse current color.icon { stroke: currentColor; }View examples
Preserve non-color cuea { text-decoration: underline; }View examples

Color is both design and information. Define paired foreground/background tokens, use perceptual color spaces for deliberate scales, provide sRGB fallbacks where required, declare supported schemes, and allow user contrast or forced-color preferences to override decorative choices.

Step by step

Detailed examples

01

Start with explicit fallback colors

Hex, rgb(), and hsl() describe sRGB values widely. Alpha composites with whatever is behind it, so contrast must be tested on actual layers. Put a supported fallback before a newer declaration because invalid later values are ignored.

Fallback then wide-gamut enhancement
.brand { color: #1d4ed8; color: color(display-p3 0.12 0.3 0.9); }
.overlay { background: rgb(15 23 42 / 65%); }
Back to quick reference ↑
02

Build scales in a perceptual space

OKLCH separates approximate perceived lightness, chroma, and hue, making systematic variations easier than RGB arithmetic. Some values are outside a display gamut and require mapping. color-mix and relative colors should name an interpolation space and remain bounded by contrast requirements.

Derived brand tokens
:root { --brand: oklch(55% .2 260); --brand-soft: color-mix(in oklab, var(--brand) 15%, white); --brand-hover: oklch(from var(--brand) calc(l - .08) c h); }
Back to quick reference ↑
03

Declare support before selecting theme values

color-scheme tells the browser which schemes the page can render and affects controls, scrollbars, and system colors. light-dark chooses by used scheme; a media query can build a larger token set. User choice should override OS preference when the application offers a persistent theme control.

Two-scheme token set
:root { color-scheme: light dark; --surface: light-dark(#fff, #0f172a); --text: light-dark(#172033, #e6edf7); }
body { background: var(--surface); color: var(--text); }
Back to quick reference ↑
04

Let controls and icons inherit theme context

accent-color styles the accent of supported form controls but does not replace labels or states. currentColor makes icons follow text and forced palettes. Avoid removing native appearance unless the full control behavior and contrast have been tested.

Theme-aware checkbox and icon
form { accent-color: var(--brand); }
.icon { inline-size: 1em; stroke: currentColor; fill: none; }
button:disabled { color: GrayText; }
Back to quick reference ↑
05

Respect user-enforced palettes

In forced-colors mode the user agent replaces many author colors. System color pairs expose the active palette. Avoid forced-color-adjust:none except for content whose exact colors are essential, and restore boundaries with system-color borders when background images or shadows disappear.

Restore a card boundary
@media (forced-colors: active) { .card { border: 1px solid CanvasText; box-shadow: none; } .card a { color: LinkText; } }
Back to quick reference ↑
06

Keep meaning independent of hue

Validate text, controls, focus indicators, states, and adjacent boundaries against every theme and image state. Add icons, text, patterns, or decoration for status differences. Do not assume a mathematically related palette automatically meets accessibility contrast.

Error with redundant cues
.error { color: #b91c1c; border-inline-start: .25rem solid currentColor; }
.error::before { content: "Error: "; font-weight: 700; }
a { text-decoration: underline; text-underline-offset: .18em; }
Back to quick reference ↑

Local code tester

Tune an adaptive color system

Change perceptual colors and inspect light, dark, native-control, and forced-color behavior.

Runs in your browser
Preview

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. World Wide Web ConsortiumCSS Color Module Level 4w3.org
  2. World Wide Web ConsortiumCSS Color Adjustment Module Level 1w3.org
  3. World Wide Web ConsortiumMedia Queries Level 5w3.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback