About the Color Converter
Four notations, one color. A tour of why the same red has four different strings, the math that ties them together, and when each one is the right one to reach for. Back to the tool ↗
What this tool does
Type a color into any of four fields — HEX, RGB, HSL, or HSV — and the other three update in the same frame, alongside a live swatch you can scrub with hue, saturation, and lightness sliders. Every conversion is closed-form arithmetic over three 8-bit channels. The whole thing fits on roughly fifty lines of TypeScript, runs entirely in your browser, and never makes a network request. The thirty-second use case is the same every time: a designer hands you one notation, the system you are wiring into expects another, and you need an answer in less time than it takes to switch tabs.
A short history of computer color models
Computer displays inherited their color model from the cathode-ray tubes that preceded them. A CRT mixes three phosphors — red, green, blue — in additive proportion, so the natural way to address a pixel is to send three numbers, one per gun. That is RGB, and it is a hardware fact, not a design choice. The web inherited RGB and then packed it into a byte-thrifty notation because early browsers needed to ship color in markup: three octets became six hexadecimal digits with a leading #. HEX is not a color model; it is RGB in a more compact dress.
Designers found RGB unintuitive almost immediately. Asking “make it a little more saturated” means changing all three channels in concert; asking “rotate the hue” means thinking in three dimensions at once. At SIGGRAPH 1978, Alvy Ray Smith proposed HSV (hue / saturation / value), reshaping the RGB cube into a hexcone that designers could think about directly: pick a hue on the rim, pull saturation toward the center, push value toward the top to brighten. The same year, Joblove and Greenberg proposed HSL(hue / saturation / lightness), a bicone variant in which pure white and pure black sit at opposite poles and 50% L is the “pure” hue. Both models are simple cylindrical transforms of the sRGB cube; both are still in CSS today; neither is perceptually uniform, which the next generation of color spaces (CIELAB, OKLCH) was invented to fix. See citation [1] for the current CSS spec and citation [2] for the original HSV paper.
The math, plainly
The HEX RGB mapping is trivial base-16 packing: two hex digits per channel, three channels, a fourth byte for alpha when present. The interesting math is RGB HSL/HSV. Given normalized RGB in [0, 1], compute max and min of the three channels, then chroma = max − min. The hue is determined by which channel is max: red-max gives a hue in the yellow-red sector, green-max in the green-cyan sector, blue-max in the blue-magenta sector. Saturation and lightness (or value) fall out of the same max/min pair via two different normalizations — that is the entire difference between HSL and HSV.
hue = 60 * sector_offset_from(max_channel, r, g, b) chroma = max − min hsv.s = chroma / max // when max > 0 hsv.v = max hsl.l = (max + min) / 2 hsl.s = chroma / (1 − |2L − 1|)
Round-tripping any color through these formulae in pure floating point is exact, but rounding the result back into 8-bit integers (which RGB demands) introduces at most one unit of error per channel. That is invisible to the eye but visible in unit tests. This tool uses round-half-to-even (banker’s rounding) on the integer paths rather than the JavaScript default of round-half-up, because round-half-up biases every conversion slightly bright — over millions of round-trips it skews palettes in a measurable direction. Half-to-even keeps the bias symmetric.
HSL vs. HSV: which lies about what
The naming tempts you to read L = 50% as “medium brightness” and V = 100% as “white,” and both are wrong. HSL’s lightness is the midpoint of the largest and smallest channel; a pure saturated red sits at L = 50% and feels much darker than a pale cream at L = 90%. HSV’s value is the largest channel; pure red is V = 100% but so is pure white. Neither is a perceptual measure of how bright a color looks — they are geometric re-projections of the RGB cube. CSS Color 4 adds oklch(), which fixes this by using a perceptually uniform space (OKLab) so equal numeric changes in lightness feel like equal perceptual changes. For brand-system work where consistency across hues matters, OKLCH is the right tool; HEX/RGB/HSL/HSV remain the right tools for matching whatever string is sitting in someone else’s file.
When to reach for which notation
HEXis for sharing a color verbatim — in a Slack message, a brand doc, a hex picker. RGB is for image pipelines and canvas: most decoder APIs hand you bytes, so working in RGB skips a transform. HSLis for tweaking by hand; if a designer asks for “the same color but a little less saturated,” HSL lets you do that with one slider. HSV is what color-picker UIs use under the hood because its constant-value plane is a single rectangle, which is what those square hue/saturation pickers actually map to. None of these is wrong for a use case; they are all the same color expressed in the notation that matches the question.
What the tool does not do
No CIELAB, OKLCH, OKLab, or other perceptual spaces — for those reach for the palette tool, which already needs perceptual math. No CMYK, because print pipelines are a different audience. No named CSS colors (tomato, rebeccapurple) and no alpha math beyond round-tripping the eighth byte of an 8-digit hex. The tool does not remember a recent color across reloads; nothing is persisted, by design.
How to choose (when options matter)
Turn on Decimals in HSL / HSVwhen you are converting a color you intend to feed back into a system that round-trips through the same notation — the extra decimal stops the slow drift from naive integer rounding. Keep it off for casual sharing. The 8-digit hex alpha row only appears when the input has alpha; if it never shows up, you can ignore it. Reach for the sliders when you want to nudge a color toward a target rather than type one in; reach for the input fields when you have a specific string to paste.
References
- W3C (Working Draft). CSS Color Module Level 4. The canonical browser-side definitions of
rgb(),hsl(), hex notation, 8-digit hex with alpha, and the perceptualoklch()referenced above. - Smith, A. R. (1978). Color gamut transform pairs. Computer Graphics(SIGGRAPH ’78 proceedings), 12(3), 12–19. The original HSV paper and the source of the hexcone formulation used in every modern color picker.
Related tools
- /tools/color-palette — Color palette extractor— pull a 3–12 swatch palette from any image, locally.
- /tools/qr-code — QR code generator— encode any URL or text, foreground/background in any HEX.
- /tools/base64 — Base64, URL & HTML encoder— round-trip strings between encodings, all in-browser.