RGB isn't enough: HSL, CMYK, and OKLCH color notations
In the previous post, How computers make color: RGB, HEX, and binary, we saw that a color is just three numbers — red, green, blue, each 0–255. Screens run on those numbers just fine. But the moment a human starts working with color, RGB gets awkward fast.
RGB is convenient, but not intuitive
“A slightly brighter red.” How do you make that with RGB? You have to nudge all three channels up together. “Just lower the saturation a little” — looking at raw RGB values gives you no clue which number to change. “Print this color on paper exactly as it looks on screen” — that’s simply impossible with RGB alone.
With RGB, you have to raise R, G, and B together. Get the balance wrong and the hue shifts.
Looking at raw RGB values gives you no clue which channel to change.
Screen RGB doesn't translate directly to ink.
Other color notations were invented to solve exactly these problems.
HSL — the way humans think
HSL breaks color down into three properties: hue, saturation, and lightness. hsl(14, 100%, 60%) is the same color as #FF5733, but what each component means is immediately clear.
The "name" of the color — red, green, blue, and so on.
Color intensity. 0% = gray, 100% = vivid.
Brightness. 0% = black, 100% = white.
If RGB is the computer’s language, HSL is the designer’s language. It lets you work with the same color from the perspective of what you want to change.
Hue — color as a 360° wheel
Hue wraps around like a clock, from 0° to 360°. 0° and 360° are the same red.
Saturation — how vivid the color is
Keeping the same hue and reducing saturation moves the color progressively toward gray.
Lightness — from black to white
L at 0% is always black, L at 100% is always white. 50% is the color’s “native” brightness.
HSL’s real power — building palettes
Hold the hue constant and step through L values, and you get a naturally cohesive color scale. Doing the same thing in RGB requires calculating all nine cells by hand. With HSL, you just step L from 12% to 92%.
Both palettes above can be generated in a single CSS block.
:root {
--terra-100: hsl(14 60% 92%);
--terra-200: hsl(14 60% 82%);
--terra-300: hsl(14 60% 72%);
/* ... just step L by 10 each time */
}
This is where HSL shines most when building a design system.
CMYK — the language of ink
Putting color on paper instead of a screen requires a completely different system. CMYK is the ratio of four inks used by print shops.
Why “K” for black instead of “B”? Because B would be confused with Blue. The K also comes from the printing term “key plate” — the plate that all other inks are registered against.
Light gets brighter when added; ink gets darker
The biggest difference between RGB and CMYK is how they mix.
Red ink looks red because it absorbs other wavelengths of light and reflects only red back. Ink subtracts light rather than adding it, so mixing more ink makes the color darker. In theory, combining all three CMY inks should produce black — in practice, it yields a muddy brown. That’s why a dedicated black ink (K) exists.
Where CMYK is used
If you work in screen design, you’ll rarely touch CMYK. It appears only when printing on paper.
- Sending files to a print shop — business cards, posters, books, packaging. Print shops convert RGB files to CMYK on receipt.
- Print work in Photoshop / Illustrator — set the color mode to CMYK from the start.
- Brand guidelines — both the screen HEX and the print CMYK values are listed together, so the brand color looks consistent across both media.
Why screen colors differ from printed colors — Gamut
The range of colors a screen can produce (RGB gamut) and the range achievable with ink (CMYK gamut) are different. A vivid neon pink on screen simply cannot be reproduced in print — the ink to make that color doesn’t exist.
Print designers therefore select only colors within the CMYK gamut before they start. Sending an RGB design file directly to print and expecting the colors to match is a common source of disappointment.
How CMYK values are written
Each ink is expressed as a percentage: how much of that ink to lay down. 0% means none, 100% means full coverage.
Using K 100% alone produces a flat, grayish black. Print shops layer CMY underneath to achieve a deeper, richer black.
OKLCH — coordinates for human eyes
This color model came into mainstream use in the 2020s. The key idea is simple: “perceptually natural to human vision.”
Its three coordinates look similar to HSL’s:
- L — Lightness (0–1)
- C — Chroma (0–~0.4)
- H — Hue (0–360°)
HSL has a hidden problem, though. Colors at the same L = 50% can look dramatically different in perceived brightness. Compare them directly.
Yellow is blinding; blue looks nearly as dark as black. The L values are identical, but your eyes don't perceive them that way.
The hues differ, but the perceived brightness looks consistent. That's because L is designed to match human perception of lightness.
In a single line: RGB and HSL are the machine’s coordinates. OKLCH is the human’s coordinates.
L, C, H — what each one does
Here’s what happens when you change just one coordinate at a time on the same color.
Where OKLCH is used
- Uniform-brightness palettes — when you need eight category colors all at the same perceived brightness
- Automatic dark/light mode — inverting L alone produces a naturally readable dark theme
- Accessibility — the lightness contrast between text and background can be predicted precisely
- Gradients — smooth transitions without the gray band that HSL gradients often show in the middle
OKLCH was formally adopted in CSS Color Level 4 and works in all modern browsers today.
.btn { background: oklch(67% 0.18 30); } /* orange */
.btn:hover { background: oklch(60% 0.18 30); } /* L drops by 7 → darker by exactly that much */
When to use what
RGB/HEX is sufficient for most digital work. HSL is worth reaching for whenever you’re building a palette. OKLCH becomes a significant advantage when designing for dark/light mode.
Working with color in fns
Once you understand that color is just numbers, the natural next step is having your most-used colors at your fingertips. fns puts the entire flow — picking, saving, and retrieving colors — behind a single key.
Pick any color on screen with Eyedropper — ⌘+Shift+K
Eyedropper is a tool that grabs the precise color of any pixel on screen — essentially pulling the color picker that normally lives inside Figma or Photoshop out into a system-wide tool.
Press ⌘+Shift+K and fns’s Eyedropper appears, no matter what’s on screen. A pixel in a design mock-up, a region of a photo, a background color in another app — hover and click, and the exact color at that spot is captured.
- Every click saves automatically to the clipboard. No separate “copy” action needed.
- In the Eyedropper widget you can choose which format — RGB, HEX, HSL, CMYK, or OKLCH — lands in the clipboard.
- A visual preview of the captured color and the nearest system color name are shown alongside.
Eyedropper → automatic clipboard save → retrieve from the clipboard picker — the flow is unbroken. No need to open a separate utility like Digital Color Meter, and no need to hit a copy shortcut after every pick.
The clipboard recognizes color codes automatically
fns’s clipboard history detects automatically when copied text is a color code, regardless of format.
#FF5733
Standard HEX
#F53
3-digit shorthand — recognized as the same color
rgb(255, 87, 51)
rgba(...) with alpha also recognized
hsl(14, 100%, 60%)
hsla(...) with alpha also recognized
oklch(0.67 0.18 30)
Modern CSS notation
When you pull a color back from history, a plain text string gives you no clue what the color looked like. fns shows a small color chip beside each entry so you can tell at a glance.
Filter to colors only
One key filters the clipboard history to show only color codes. During a design session, when you want just the colors you’ve recently used, you don’t have to scroll past text, URLs, and code snippets.
- Type a filter keyword like
color:in the same picker → only color entries appear - Search by color name — type “blue” or “red” and matching colors are surfaced
- Similar colors are grouped visually for easy comparison
Convert a color to a different format
You can convert a stored color to a different notation right from the picker. If you copied #FF5733 from Figma and need rgb(...) for CSS, select that clipboard entry in fns and a single shortcut converts it automatically.
#FF5733
rgb(255, 87, 51)
rgb(255, 87, 51)
hsl(14, 100%, 60%)
hsl(14, 100%, 60%)
oklch(0.67 0.18 30)
No need to open a converter every time you move between Figma (HSB) and CSS (HSL/HEX/OKLCH).
Text expansion for brand colors
Register frequently-used brand colors as text snippets.
The same shorthand works in CSS, Figma’s color input, Slack messages, and code editors alike. Hunting through a brand guide to find and copy a color value every time stops being necessary.
Give fns a try to cut down the time you spend opening converters and reformatting color codes.
Curious where these numbers come from in the first place — the basics of RGB’s three channels, binary, and HEX notation? Start with How computers make color: RGB, HEX, and binary.