← Back to Blog

Advanced Color: Comfortable Codex Theme Palettes with HSL and OKLCH

2026-10-05

A codex theme hsl color palette reads differently from a list of hex codes, and that difference decides whether a theme stays calm through a long session or starts grating after an hour. hsl() splits a color into hue, saturation and lightness, three numbers you can reason about one at a time. Most theme authors never leave hex, so most palettes get built by guessing in a color picker.

Why hex is a poor format for editing colors

A hex code packs three channels into six characters. Change one character and red, green and blue all move together in a direction you cannot predict from looking at the string. Asking for a slightly darker version means opening a picker and hoping.

  • #3fb950 tells you where that green sits in sRGB and nothing about how bright it reads
  • Two colors you think share brightness can differ by fifteen points on screen
  • Every small adjustment becomes a round trip to a picker
  • Nothing in the string hints at which value to move to darken it

What each HSL number controls

hsl(210 60% 45%) reads as a blue leaning hue, moderate saturation, lightness sitting below the middle. Darkening means pulling the third number down. Desaturating means pulling the second down. Once you trust that mapping you can write the whole palette by hand instead of clicking around a picker.

  • Hue: the angle on the wheel, 0 to 360. Move it and you change which color family you are in
  • Saturation: distance from grey. 0% is grey, 100% is as loud as the gamut allows
  • Lightness: position between black and white, and the value you edit most
  • Body text on a dark background usually lands between 70% and 85% lightness

Where OKLCH differs, and whether it is worth it

OKLCH is perceptually uniform, which means a given lightness value looks equally bright whatever the hue. HSL does not manage that. Two colors both set to 60% lightness in HSL can look wildly different, with yellow reading much brighter than blue. In OKLCH they line up, so the lightness ladder you lay out is actually a ladder.

The second difference is chroma instead of saturation. Chroma is not clipped by the display gamut, so values stay consistent when you move between hues. The trade-off sits in the toolchain: any browser recent enough to run Codex resolves oklch(), but older design tools preview it wrong. Keep a hex or hsl() fallback line above each declaration.

  • oklch(65% 0.13 250): lightness, chroma, hue, in that order
  • Lightness is perceptual, so 65% reads the same whether the hue is blue or yellow
  • Chroma above roughly 0.37 leaves sRGB and gets clipped on most displays
  • Keep a hex or hsl() fallback line above every oklch() declaration

Converting a theme you already have

  • List every color in the theme file and note which slot each one fills
  • Convert each value to HSL and write down the resulting triplet
  • Group them by role: backgrounds, body text, syntax, accents
  • Set target lightness steps per role before you touch any hue
  • Move to OKLCH once the structure holds, one role at a time

Checks that catch trouble before you commit

  • Compare body lightness against background lightness and keep the gap above 40 in OKLCH terms
  • Squint at the screen: if two syntax colors merge, separate them in hue rather than lightness
  • Turn screen brightness low and look again, which is where weak contrast themes fall apart
  • Check both light and dark schemes, since any role you skip falls back to the default
  • Look at the scrollbar and the gutter, usually the last elements anybody colors

Color is the one part of a theme that touches every line you read, so an hour spent on it upfront pays back for months. Compare against finished work in the gallery at https://codex-skin-studio.shop/en/gallery/, and the rest of the entry points sit on https://codex-skin-studio.shop/en/.

Frequently asked questions

Should I write my Codex theme in OKLCH or keep hex?

Use OKLCH for anything you expect to adjust later, and keep a hex or hsl() fallback line above each declaration. A theme that is finished and will never be edited again is fine in hex. Anything you plan to tune by hand gets much easier in a perceptual format.

Does OKLCH work everywhere Codex runs?

Current Chrome and Safari both support it. Codex renders through Chromium, so if your Codex build runs, oklch() resolves. The trouble is in external tools, where older design software previews it incorrectly, which is exactly why the fallback line earns its keep.

How many colors should a theme palette hold?

Somewhere between eight and twenty. Below eight and every element competes for the same few slots. Past twenty you are maintaining distinctions nobody perceives while reading code.

Why does my HSL palette look uneven across hues?

Because HSL lightness is not perceptual. Yellow at 60% lightness looks considerably brighter than blue at 60%. That gap is the specific problem OKLCH was built to close, and the reason to move once your structure settles.

Related Posts