Design & Media · Guide · File & Format Converters
How to convert color formats
Color model mapping, HEX↔RGB math, RGB↔HSL formula, sRGB vs Display P3, OKLCH for perceptual uniformity, CMYK for print, precision.
HEX, RGB, HSL, HSB, OKLCH, CMYK — the same color has many representations, and each one makes sense in a specific context. HEX is compact and copy-friendly. HSL is intuitive for tweaking. OKLCH is perceptually uniform. CMYK is for print. Converting between them is mechanical, but picking the right one for the job and avoiding gamut clipping / precision loss is where most confusion lives. This guide covers the color models, how conversions actually work, sRGB vs wide gamut, the new CSS Color 4 formats (oklch, color(), display-p3), print considerations, and how to avoid losing fidelity in round-trips.
Advertisement
The common formats
HEX: #ff5733. Six hex digits for RGB, or eight for RGBA. Compact, copy-paste friendly, the default for design tokens.
RGB / RGBA: rgb(255, 87, 51). Red, green, blue as 0-255 integers (or 0-100% or 0-1 float). Alpha channel as 0-1. Direct representation of display output.
HSL / HSLA: hsl(12, 100%, 60%). Hue (0-360), saturation (%), lightness (%). Easier to tweak than RGB — want a darker red? Lower lightness, keep hue.
HSB / HSV: Hue, saturation, value. Like HSL but with different lightness semantics. Photoshop uses HSB. Not supported directly in CSS.
OKLCH / OKLAB: oklch(67% 0.18 34). Lightness, chroma, hue in a perceptually uniform color space. Interpolates smoothly without muddy midpoints. CSS Color 4.
CMYK: cmyk(0%, 66%, 80%, 0%). Cyan, magenta, yellow, key (black). For print. Not supported in CSS; used in design tools and print workflows.
HEX ↔ RGB conversion
Purely mechanical. HEX is base-16 encoding of 0-255 integers, two digits per channel:
#ff5733 ff → 255 → R 57 → 87 → G 33 → 51 → B = rgb(255, 87, 51)
3-digit HEX: #f53 is shorthand for #ff5533 — each digit is duplicated. Handy but limits you to 4096 colors (16³).
8-digit HEX with alpha: #ff573380 — last two digits are alpha as 0-255 (80 = 128 = ~50%). CSS Color 4 supports this.
RGB ↔ HSL conversion
Not mechanical — involves min/max math to find hue and lightness. The formula:
R' = R/255, G' = G/255, B' = B/255 max = max(R', G', B'), min = min(R', G', B') L = (max + min) / 2 S = (max-min) / (1 - |2L-1|) // or 0 if max=min H = depends on which is max: if R max: H = 60 * ((G'-B')/(max-min) mod 6) if G max: H = 60 * ((B'-R')/(max-min) + 2) if B max: H = 60 * ((R'-G')/(max-min) + 4)
You don’t need to memorize this — libraries and converter tools handle it. But knowing the math helps you understand why hsl(0, 0%, 50%) is gray (saturation 0 makes hue irrelevant).
sRGB vs wide gamut
Traditional HEX / RGB / HSL assume sRGB — the web’s default gamut, covers ~35% of visible colors. Modern displays (iPhone, MacBook, high-end monitors) can show Display P3 (~45%) or Rec2020 (~75%).
HEX can’t represent P3 colors. If your brand has a vivid red that looks dull on your phone, you’re probably clipping to sRGB:
/* sRGB only */
.brand { color: #ff0000; }
/* P3 capable, sRGB fallback */
.brand {
color: #ff0000;
color: color(display-p3 1 0 0);
}CSS Color 4 color(display-p3 r g b) opens up the wider gamut. Browsers ignore it on sRGB displays and use the fallback.
OKLCH — perceptually uniform
Mixing HSL colors linearly produces muddy midpoints: midpoint of hsl(240, 100%, 50%) (blue) and hsl(0, 100%, 50%) (red) is gray-purple, not a pleasant transition.
OKLCH fixes this by using a color space where equal numeric steps look equally different to the eye. Transitions in OKLCH stay vivid and smooth. Recommended for gradients, chart color scales, and theme token generation.
/* Gradient in sRGB — may look muddy */ background: linear-gradient(#ff0000, #0000ff); /* Gradient in OKLCH — perceptually smooth */ background: linear-gradient(in oklch, #ff0000, #0000ff);
CMYK conversion — and why it’s lossy
Monitor colors come from emitted light (additive RGB); print comes from absorbed light (subtractive CMYK). The conversion is fundamentally imperfect — CMYK can’t reproduce all sRGB colors (especially bright blues, greens), and sRGB can’t reproduce all CMYK colors (especially deep browns, some yellows).
The simple formula:
K = 1 - max(R, G, B) C = (1 - R - K) / (1 - K) M = (1 - G - K) / (1 - K) Y = (1 - B - K) / (1 - K)
This works for basic conversion but ignores ink characteristics, paper, press calibration. Real print workflows use ICC profiles (GRACoL 2013, Fogra 51) for accurate conversion. Design tools (Illustrator, InDesign) do this automatically.
Practical tip: don’t design in CMYK for screens. Design in sRGB (or Display P3 with care), and hand off to print with ICC-profile conversion in the design tool.
Precision and round-tripping
HEX → RGB is exact (1-to-1 mapping). RGB → HSL → RGB can lose a tiny amount of precision due to floating-point math, but it’s usually <1% per channel. Safe for most uses.
sRGB → P3 → sRGB is lossless if the original was in sRGB gamut. Otherwise, the P3 → sRGB step clips.
sRGB → CMYK → sRGB is lossy. Don’t round-trip unless you have to.
Accessibility and contrast
Strength of a color isn’t the same as its contrast against a background. WCAG contrast ratios (4.5:1 for body text) are calculated from luminance (a weighted combination of R, G, B — not straight brightness).
Converting to HSL and matching lightness doesn’t guarantee matched contrast. Always verify with a contrast checker.
Color picker workflows
Design tools: Figma, Sketch, Photoshop all let you input and switch between HEX, RGB, HSL, HSB. Figma supports OKLCH since 2024.
Dev tools: Chrome DevTools and Firefox DevTools have color pickers that let you switch between representations on any color value.
CLI / build: libraries like culori (JS), colour-science (Python) handle modern color math including OKLCH, Display P3, and ICC profiles.
Common mistakes
Copy-pasting CMYK from print files into web. Browsers don’t understand CMYK. Convert to sRGB via your design tool.
Expecting round-trips through CMYK to be lossless. They’re not. Keep sRGB as source of truth; export CMYK per print job.
Making gradients in sRGB that look muddy. Use in oklch or in hsl longer hue.
Forgetting Display P3 fallback. If you use color(display-p3 ...), always provide a HEX fallback for older browsers and SDR displays.
Matching lightness and expecting contrast parity. WCAG uses luminance, not HSL lightness. Check with a contrast tool.
Using 3-digit HEX for gradients or critical colors. Only 4096 colors available; banding possible. Use 6-digit.
Run the numbers
Convert HEX / RGB / HSL / HSB / OKLCH with the color converter. Pair with the color picker to sample from real designs, and the contrast checker to validate accessibility.
Advertisement