THE OPEN STUDIO / GRAPHICS

How does a browser think in color?

Mix a color with white, learn what modern color spaces solve, and understand why beautiful palettes still need contrast checks.

Interactive · Modern CSSPlain HTML routeOpen source

Color is a measurement—and an experience.

Traditional CSS used named colors, hexadecimal RGB and HSL. Those are useful, but RGB values are tied to channels of light, not how evenly people perceive changes in brightness or saturation. Designers can choose two colors with similar-looking numbers and end up with very different visual weight.

Modern CSS adds spaces such as OKLCH, designed around perceptual lightness, chroma and hue. It also adds color-mix() so the browser can calculate blends without a preprocessor or a collection of pre-generated shades. Different interpolation spaces can make the very same color mixture look surprisingly different.

Mix a color with its surroundings.

Slide the hue and watch the base color and its tint respond. The tint uses color-mix(in oklch, ...), which may produce a more perceptually coherent result than naïve channel averaging. These decorative swatches are not used as backgrounds for essential text.

LIVE EXPERIMENT / COLORChange one variable at a time
Base color
65% color + 35% white
CSS THE BROWSER IS USING

These controls update CSS custom properties; the example's HTML stays the same.

Try a warm hue near 30 degrees, then cool hues near 200 degrees. Notice that the amount of pigment you perceive doesn't stay perfectly constant across all colors. Human perception is complicated; color models are tools, not guarantees.

Design tokens, space and the cascade.

:root {
  --brand: #15766d; /* fallback */
  --tint: #b5d8d3;
}
@supports (color: color-mix(in oklch, red, white)) {
  :root {
    --brand: oklch(50% 0.11 175);
    --tint: color-mix(in oklch, var(--brand) 65%, white);
  }
}
.card { background: var(--tint); }

Custom properties store values that can be reused and inherited. oklch() expresses perceived lightness, chroma and hue. color-mix() calculates a mixture in a chosen space. CSS layers and scope can further help manage large designs, but a beginner can start with simple variables and meaningful names.

Color functions are browser features: CSS declares the operation and the browser computes the result. You generally do not need to generate hundreds of shades with JavaScript.

Choose a palette for the task.

  • Use semantic token names such as --text, --surface and --accent, not only “blue-4.”
  • Use OKLCH when perceptual adjustments or wide-gamut work benefit the design.
  • Keep an established fallback color when targeting older clients or experimental syntax.
  • Don't choose your entire accessibility strategy from a color picker screenshot.

Contrast is contextual.

For common WCAG 2.2 AA situations, ordinary text needs at least a 4.5:1 contrast ratio, large text 3:1, and relevant non-text interface graphics or boundaries often need 3:1. This isn't the entire guideline, and special cases exist. Never rely on hue alone to communicate “error,” “success,” or selection.

Test dark mode, high-contrast settings and forced-colors. Some colors will be replaced by system choices; a meaningful border or label must survive. Heavy background blending can be expensive and may make contrast unpredictable.

Build a palette with a purpose.

Break it

Set gray text on a gray-green card until it looks elegant but becomes hard to read. Measure the contrast. What would make it usable without losing the mood?

Build it

Create five named design tokens for a reading page. Provide a light and dark scheme, then test them at 200% zoom and with high-contrast settings. Explain where you used modern color functions and where you deliberately chose a simple fallback.

Go a little deeper.