Advanced colour in CSS – relative colour syntax, contrast-aware choices, and wide-gamut displays. Hex codes copied from a brand PDF are a starting point, not a system.
Relative colour syntax
Derive variants from an existing colour without Sass:
:root {
--brand: oklch(0.55 0.18 250);
--brand-hover: oklch(from var(--brand) calc(l + 0.08) c h);
--brand-muted: oklch(from var(--brand) l calc(c * 0.4) h);
--brand-on: oklch(from var(--brand) 0.98 0.02 h);
}
Adjust lightness, chroma, or hue relative to a token. When brand blue changes, hover and muted variants update automatically. Prefer OKLCH or LCH for perceptually even steps – RGB math darkens blues differently from yellows.
colour-mix() for simple blends
:root {
--surface: #ffffff;
--text: #1a1a1a;
--border: color-mix(in oklab, var(--text) 12%, var(--surface));
--link: color-mix(in oklab, var(--brand) 85%, var(--text));
}
color-mix() is straightforward when you need a halfway point. Relative syntax wins when the adjustment is parametric (always 8% lighter).
Contrast and readability
WCAG contrast ratios still matter. Use color-contrast() where supported to pick a readable foreground from a list:
.badge {
--bg: var(--brand);
background: var(--bg);
color: color-contrast(var(--bg) vs white, black);
}
Where color-contrast() is unavailable, define paired tokens upfront – --brand and --brand-fg – and audit with a contrast checker in CI or design review.
Wide gamut (P3)
sRGB hex cannot show every colour modern displays render. Declare vivid accents in Display P3 when it helps:
:root {
--accent: #007aff; /* sRGB fallback */
--accent: color(display-p3 0.12 0.45 1);
}
@supports (color: color(display-p3 1 1 1)) {
.hero {
background: linear-gradient(
135deg,
color(display-p3 0.2 0.5 1),
color(display-p3 0.6 0.2 0.9)
);
}
}
Always provide an sRGB fallback first. Most users will not notice P3 gradients; brand-heavy marketing pages sometimes do.
Forced colours and colour-scheme
@media (forced-colors: active) {
.btn {
border: 2px solid ButtonText;
background: ButtonFace;
color: ButtonText;
}
}
:root {
color-scheme: light dark;
}
Windows high-contrast mode and similar settings override your palette. Use system colours where needed instead of fighting the OS. color-scheme hints native form controls and scrollbars toward light or dark.
Practical token shape
- Store base colours as custom properties in OKLCH.
- Derive hover, muted, and on-colour variants with relative syntax.
- Document minimum contrast pairs in your design system.
- Test dark mode tokens separately – relative adjustments from a light brand colour do not always land well on dark surfaces.
The next tutorial covers typography systems – scales for UI and long-form reading, variable fonts, and OpenType features.

