The same three numbers
| Notation | The value | Reads as |
|---|---|---|
| HEX | #394DFE | three channels in base 16 |
| RGB | rgb(57, 77, 254) | the same channels in decimal |
| HSL | hsl(234, 99%, 61%) | hue, saturation, lightness |
Hex packs each channel into two digits from 00 to FF. RGB writes those same channels as 0 to 255. HSL describes the colour by hue angle and two percentages instead, which is a different way of naming the same pixel.
Where hex belongs
Design handoff and stylesheets. Six characters, no punctuation, nothing to mistype. Figma, a Tailwind config, a brand page and a CSS variable all take it directly, and two people reading #394DFE cannot disagree about what it says.
The conversion I reach for most often is not the one this guide is named after. It is SwiftUI. Color(red: 0.22, green: 0.30, blue: 1.00) needs every channel divided by 255 first, which is the step nobody wants to do in their head.
Klipto also reads the notation you copied, so an hsl() string gives you hex back. There is no input format to pick, and no direction to set.
Where rgb() earns its place
Alpha, and values that come out of code. rgba(57, 77, 254, 0.4) says 40 percent opacity plainly. When a colour is assembled by a script or a Sass function, three decimal numbers are easier to produce than a base-16 string you have to pad.
Hex can carry alpha too, and people forget. Eight digits means RGBA: #394DFE80 is that blue at roughly half opacity, and current browsers handle it. Four-digit shorthand does the same with one digit per channel. So rgba() is not the only route to transparency, it is just the readable one.
HSL when you are adjusting by hand
Lightness is a number you can move. Take hsl(234, 99%, 61%), drop it to 45 percent, and you have a darker version of the same hue for a hover state. Doing that in hex means converting, adjusting three channels, and converting back.
The trap: hex has no colour space
A hex code is three bytes and nothing else. It carries no tag saying which colour space those bytes belong to, so every piece of software just assumes sRGB. That assumption is invisible until something disagrees with it.
AppKit disagrees. NSColor(red:green:blue:alpha:) builds the colour in deviceRGB, not sRGB, and on a wide-gamut display the same numbers show up visibly different from the hex you started with. Use NSColor(srgbRed:green:blue:alpha:) instead. The bug is not in the notation. It is in the space nobody wrote down.
What I use
Hex by default, because it survives being pasted into anything. rgb() when opacity or a computed value is involved, HSL when I am building shades of one hue.
For a one-off value in a browser, try it free in your browser. On my own Mac, Klipto puts every notation in the paste preview, so the copied colour arrives in whatever form the open file wants, offline, with no tab involved.