CSS gives you three everyday ways to write the same color — hex, rgb() and hsl() — and all three point into the same sRGB color cube. This guide shows what each model actually encodes, walks one color, #4F7CFF, through a full hex to RGB to HSL conversion with the math, and helps you pick the right notation for design tokens, theming and quick edits.
What each color model is
Hex: base-16 shorthand for RGB
A hex code like #4F7CFF is not a separate color space — it is RGB written in base 16. After the #, three two-digit pairs hold red, green and blue: 4F is red, 7C is green, FF is blue. Each pair runs from 00 to FF, which is 0 to 255 in decimal. The three-digit shorthand doubles every digit, so #4F8 expands to #44FF88.
RGB: three channels from 0 to 255
rgb(79, 124, 255) states the same channels directly in decimal: red, green and blue intensities on a 0-255 scale, matching how a monitor mixes light: 0 is off, 255 is full strength, so rgb(0, 0, 0) is black and rgb(255, 255, 255) is white.
HSL: hue, saturation, lightness
hsl(225, 100%, 65%) describes the color the way people talk about color. Hue is an angle on the color wheel from 0 to 360: 0 is red, 120 is green, 240 is blue. Saturation is a percentage from flat gray (0%) to fully vivid (100%). Lightness runs from black (0%) through the pure hue at 50% up to white (100%). Same color as the values above — different coordinates.
Worked example: hex to RGB to HSL
Step 1: hex to RGB conversion
Convert each pair from base 16: 4F = 4 x 16 + 15 = 79, 7C = 7 x 16 + 12 = 124, FF = 15 x 16 + 15 = 255. So #4F7CFF becomes rgb(79, 124, 255).
Step 2: RGB to HSL
Normalize the channels to the 0-1 range: r = 79/255 = 0.310, g = 124/255 = 0.486, b = 255/255 = 1.000. The maximum is 1.000 (blue) and the minimum is 0.310 (red).
Lightness: L = (max + min) / 2 = (1.000 + 0.310) / 2 = 0.655, so about 65.5%.
Saturation: S = (max - min) / (1 - |2L - 1|) = 0.690 / 0.690 = 1, so 100%.
Hue: because blue is the largest channel, H = 60 x (4 + (r - g) / (max - min)) = 60 x (4 - 0.256) = 224.7 degrees.
Result: hsl(224.7, 100%, 65.5%), which rounds to hsl(225, 100%, 65%). Some converters truncate and print hsl(224, 100%, 65%) — the same color.
Hex vs RGB vs HSL at a glance
| Hex | RGB | HSL | |
|---|---|---|---|
| Readability | Compact but hard to read at a glance | Channels read as light intensities, still three abstract numbers | Reads like plain English: hue, vividness, brightness |
| Editing ease | Hard: darkening a color means recomputing every pair | Moderate: tweak channels, but they interact | Easy: move one slider (usually lightness) and keep the rest |
| Alpha syntax | 8-digit hex, e.g. #4F7CFFCC (CC = 204/255 = 80%) | rgba(79, 124, 255, 0.8) or rgb(79 124 255 / 0.8) | hsla(225, 100%, 65%, 0.8) or hsl(225 100% 65% / 0.8) |
| Typical use | Brand palettes, design handoff, CSS custom properties | Canvas, ImageData and other JS APIs that speak channels | Theming, hover states, generated color scales |
When to use which
Use hex for design tokens and documentation. It is the most compact form, every design tool displays it first, and it copies cleanly between Figma, style guides and stylesheets — nothing needs converting at handoff.
Use RGB when code already speaks in channels. The canvas fillStyle, ImageData pixel arrays and many charting libraries work in red, green and blue integers, so staying in RGB avoids round-trips.
Use HSL for systematic variations. Programmatic lightness shifts are where HSL wins: a button at hsl(225, 100%, 65%) can darken to hsl(225, 100%, 57%) on hover and hsl(225, 100%, 50%) when pressed, changing only one number while hue and saturation stay put. Doing the same in RGB means recomputing three interdependent channels. One caveat: HSL lightness is not perceptual — red hsl(0, 100%, 50%) and blue hsl(240, 100%, 50%) share the same L but differ greatly in perceived brightness, so measure contrast directly.
CSS Color Level 4: modern syntax notes
The current CSS Color Module Level 4 keeps all three models but modernizes how you write them:
- Space-separated syntax. Commas are now optional legacy. The modern form is
rgb(79 124 255 / 0.8)andhsl(225 100% 65% / 80%), with the alpha after a slash. - rgba() and hsla() are aliases. They still work everywhere, but they are the same functions as
rgb()andhsl()— the four-argument comma form is simply the old spelling. - Hex gained alpha too. Eight-digit
#RRGGBBAAand four-digit#RGBAcodes append opacity, so#4F7CFFCCis our blue at 80%. - New companions. Level 4 also adds
hwb(),lab(),lch(),oklab()andoklch();oklch()in particular fixes HSL's uneven-perceived-brightness problem while keeping the same dial-based mental model.
To see all three formats of one color side by side, paste #4F7CFF into the Color Converter — it converts instantly in your browser.