Colors on screens are just numbers, but the formats vary wildly — HEX for designers, RGB for traditional CSS, HSL for intuitive manipulation, OKLCH for perceptually uniform spaces, and Tailwind classes for utility-first workflows. This picker holds all five in lockstep: edit any field, the other four resolve in microseconds and the swatch updates in place. Everything runs in your browser; nothing is sent to a server.
Color spaces: why one color has five names
A color on screen is, at the lowest level, three voltages — how hard the monitor drives its red, green, and blue subpixels. The reference standard for those voltages is sRGB (IEC 61966-2-1), ratified in 1996 and still the safe baseline for cross-device web work. Every HEX and every plain rgb() value in CSS lives in sRGB. Modern Apple displays — iPhone, iPad Pro, MacBook Pro — render the wider Display P3 gamut, which contains roughly 25% more color volume and reaches deeper reds and greens that sRGB cannot represent.
HSL, OKLCH, and the Tailwind palette are not separate color spaces in the gamut sense — they are different parameterisations of the same sRGB cube. HEX/RGB describe the cube in raw coordinates. HSL rotates it into hue/saturation/lightness for intuitive editing. OKLCH reshapes it to match human perception. The Tailwind class names are a curated 244-point subset designed for product UI.
HEX and RGB: the literal voltages
HEX is the designer's shorthand for an sRGB triple. #ef4444 means red 0xef (239), green 0x44 (68), blue 0x44 (68); the same color in CSS as rgb(239, 68, 68). The three-digit form #f44 expands by doubling each nibble: #f44 → #ff4444. The picker accepts both forms, normalises to lowercase six-digit hex on commit, and rejects malformed input inline rather than silently picking a fallback.
RGB is HEX with the parsing stripped away. Designers tend to copy HEX from Figma, engineers tend to type RGB directly into CSS-in-JS literals. There is no information difference. The eight-digit HEX form with alpha (#ef4444cc) is recognised by browsers but this picker handles three-channel sRGB only — alpha is a separate concern, layered on top.
HSL: intuitive but uneven
HSL was added to CSS in the late 2000s to give designers a more intuitive parameterisation: hue is the position on a 360° colour wheel, saturation is how vivid the color is, lightness is roughly how bright. Rotating the hue while holding saturation and lightness constant gives you a clean color cycle. Reducing saturation toward zero produces grey. Pushing lightness toward 100% produces white. These mappings match how people talk about color.
The catch is that HSL is geometric, not perceptual. Lightness 50% is darker for blue than for yellow — the same number maps to different perceived brightnesses depending on hue. For quick edits this is fine; for systematic work (palettes, dark-mode pairs, contrast tuning) it bites. That is the problem OKLCH solves.
OKLCH: perception as the unit
OKLab was published by Björn Ottosson in December 2020 as a blog post — not a formal paper, just a thoroughly worked-out solution to a problem in image processing. He fitted a transformation against empirical color-discrimination data (MacAdam ellipses, Luo-Rigg dataset) so that equal numerical distances in the space correspond to equal perceived distances for a human observer. The polar form, OKLCH, swaps the Cartesian a/b coordinates for chroma and hue. It was added to CSS Color Module Level 4 in late 2021.
The practical wins: interpolating between two OKLCH colors holds the perceived hue (HSL famously sags toward grey through the midpoint of complementary pairs), and adjusting lightness moves predictably across the entire spectrum. Tailwind v4 stores its entire palette in OKLCH for exactly this reason. Lightness L runs 0 to 1, chroma C runs roughly 0 to 0.4 inside sRGB (further outside, only on wide-gamut displays), hue H is degrees as in HSL. When chroma is zero the color is achromatic and hue is mathematically undefined; this picker normalises that case to H=0.
Tailwind: a curated 244-point palette
Tailwind's default color system is 22 families — slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose — each with 11 shades from 50 (lightest) to 950 (darkest). The 950 shade was added in Tailwind v3.3 (April 2023) — older codebases stop at 900. Black and white round the palette to 244 named colors.
The picker maps any sRGB color to its nearest Tailwind class by computing Euclidean distance in 8-bit channel space and returning the smallest. Δ=0 is an exact palette hit; under 20 is visually indistinguishable; above 50 means the closest shade is a noticeable shift and you should probably extend your config rather than approximate. The lookup runs on every keystroke and never blocks input.
Conversion accuracy and round-trip drift
Going HEX → HSL → HEX is lossy by a maximum of one channel per axis because HSL stores floating-point values that get quantised back to 8-bit on the way out. HEX → OKLCH → HEX can drift by two channels in extreme corners of the gamut because OKLCH passes through a linear-sRGB stage with cube roots that do not invert exactly under floating-point arithmetic. These drifts are below the threshold of perception — the eye cannot tell that your #abcdef came back as #aacdef.
For storage, always treat HEX as the source of truth. The picker's recent-inputs history follows the same rule: only the canonical HEX is persisted, and the four derived forms are recomputed on recall. Two reasons. First, smaller payload. Second, no risk that a future fix to the conversion math produces stale snapshots in your history.
EyeDropper: when the browser cooperates
The EyeDropper API lets a page sample any pixel under the cursor — anywhere on screen, including outside the browser window. The user gesture (clicking the button) is the permission grant; there is no intrusive prompt. The catch is browser support: Chromium-based engines (Chrome 95+, Edge, Opera, Brave) ship it; Firefox and Safari currently do not. The picker detects window.EyeDropper at mount time and disables the button cleanly when it's absent — rather than crashing or pretending to work.
Where OKLCH is heading in production design systems
Design systems are the leading indicator for color-format adoption. IBM Carbon, Adobe Spectrum, GitHub Primer, and the Material Design 3 color system have all migrated their published palettes toward OKLCH or close cousins of it (CAM16-UCS, CIECAM02) over the last three years. The reason is the same in every case: when designers tune contrast pairs or generate dark-mode variants algorithmically, perceptual lightness gives reproducible results across hues; HSL does not. The Design Tokens Community Group standardisation effort also picked OKLCH as the recommended color space for portable token files (W3C editor's draft, 2024). The practical implication: if your team is exporting palettes from Figma to Style Dictionary today, the canonical hand-off is increasingly OKLCH, not HEX — and pasting OKLCH back into the HEX field here gives you the exact sRGB approximation the browser will actually render.
Where the workflow earns its keep
Design-system migration is the heavy use case: you have a brand HEX, you want the closest Tailwind class for a quick prototype, and you want to see what its OKLCH lightness is before you commit to a pairing. Other patterns: tuning dark-mode pairs (hold hue, drop lightness, watch the OKLCH-L number stay sensible), eyeballing accessibility headroom (OKLCH L delta between foreground and background is a usable proxy for WCAG contrast), extracting a color from a screenshot or external app via EyeDropper, or just keeping a working palette in the recent-inputs strip while you sketch.

