CSS hsl() / oklch() String Builder

Build valid CSS hsl() or oklch() color function strings

Build correct, copy-ready CSS hsl() and oklch() color strings from numeric hue, saturation, lightness, chroma and alpha inputs. Uses modern space-separated syntax, clamps each channel to its legal range, and shows a live swatch. Runs in your browser. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is the difference between hsl() and oklch()?

hsl() describes color as hue, saturation and lightness in the sRGB gamut and is universally supported. oklch() uses the perceptually uniform OKLab space, so equal lightness values look equally bright across hues. oklch() can also reach colors outside sRGB on wide-gamut displays.

Hand-writing CSS color functions is error-prone: it is easy to forget a percent sign, mix up comma and space syntax, or push a channel out of its legal range. This builder produces a guaranteed-valid hsl() or oklch() string from plain numeric inputs and shows a live swatch so you can see the result before pasting.

How it works

Each channel is clamped to the range the CSS specification allows, then the string is assembled in modern space-separated syntax:

hsl()   →  hsl(<hue> <sat>% <light>% [/ <alpha>])
oklch() →  oklch(<L 0–1> <C 0–0.4> <hue> [/ <alpha>%])

For hsl() the saturation and lightness carry percent signs and hue is in degrees. For oklch() the lightness is a 0–1 number, chroma is an unbounded positive number (practically capped near 0.4 inside sRGB), and hue is in degrees. The alpha part is only emitted when opacity is below 100 percent.

Choosing between hsl() and oklch()

Use hsl() when:

  • You need broad browser compatibility including older engines.
  • You are working in the sRGB colour space and colours stay within standard gamut.
  • The hue, saturation and lightness mental model is already familiar to you.

Use oklch() when:

  • You are building a systematic palette and want perceptual uniformity — equal lightness steps that look equally different to the eye across all hues.
  • You need to reach wide-gamut colours on P3 and Rec2020 displays.
  • You plan to animate the colour (pairing it with @property for smooth transitions).

The practical difference becomes visible in gradients and colour ramps. An hsl() lightness ramp from 20% to 80% looks uneven — yellows appear bright at mid-lightness while blues appear much darker — because the sRGB space is not perceptually linear. An oklch() ramp from L 0.2 to L 0.8 looks even across all hues.

Worked examples

Sky blue in both functions:

  • hsl(210 80% 55%) — hue 210°, 80% saturated, 55% light.
  • oklch(0.62 0.14 240) — lightness 0.62, chroma 0.14, hue 240°.

Both look similar on screen, but the oklch version will produce a more uniform appearance if you build a palette around it by holding chroma constant and stepping lightness.

A semi-transparent overlay:

  • hsl(0 0% 0% / 0.5) — 50% opaque black.
  • oklch(0 0 0 / 50%) — same, written with percentage alpha.

The builder emits the alpha suffix only when opacity is below 100%, keeping full-opacity strings clean: hsl(210 80% 55%) rather than hsl(210 80% 55% / 100%).

Browser fallback pattern

oklch() has solid support in modern engines. For projects targeting older browsers, place an hsl() or hex declaration immediately before the oklch() line — unsupported engines ignore properties they cannot parse and keep the earlier value:

.badge {
  background: hsl(210 80% 55%);             /* fallback */
  background: oklch(0.62 0.14 240);         /* modern */
}