RGB vs Hex vs HSL: Color Codes Explained
Three Ways to Say the Same Color
Every color on your screen is produced by mixing red, green, and blue light at different intensities. RGB, Hex, and HSL are three different notations for describing these mixtures. They all produce the same colors — the difference is how you think about them.
Consider this red: rgb(232, 97, 77) = #E8614D = hsl(8, 77%, 61%). Same exact color, three formats. Each has strengths depending on what you are trying to do.
RGB: The Machine Format
Format: rgb(red, green, blue) where each value ranges from 0 to 255.
RGB maps directly to how screens work. Each pixel has red, green, and blue sub-pixels, and the RGB value tells each one how bright to be:
rgb(255, 0, 0)— full red, no green, no blue = redrgb(0, 255, 0)— greenrgb(0, 0, 255)— bluergb(255, 255, 255)— all channels max = whitergb(0, 0, 0)— all channels off = black
Best for:
- Programmatic color manipulation (adding/subtracting channels)
- Working with image data and canvas APIs
- When you need alpha transparency:
rgba(232, 97, 77, 0.5)
Weakness: Unintuitive for humans. Looking at rgb(186, 133, 72), can you picture the color? Most people cannot.
Hex: The Web Standard
Format: #RRGGBB where each pair is a hexadecimal value from 00 to FF.
Hex is just RGB written in hexadecimal notation. #E8614D means red=E8 (232), green=61 (97), blue=4D (77). It is the same information in a more compact format.
Shorthand: When each pair has identical digits, you can shorten: #FFAA00 → #FA0, #000000 → #000.
Best for:
- CSS (the most common format in stylesheets)
- Design tools (Figma, Sketch, Photoshop all use hex)
- Sharing colors (short, unambiguous, copy-paste friendly)
- Design system documentation and brand guidelines
Weakness: Same as RGB — you cannot look at #BA8548 and intuit what color it is.
Converting between hex and RGB is straightforward with a hex-to-RGB converter.
HSL: The Human Format
Format: hsl(hue, saturation%, lightness%) where hue is 0–360 degrees, saturation and lightness are 0–100%.
HSL describes colors the way humans think about them:
- Hue: The color itself — position on the color wheel (0°=red, 120°=green, 240°=blue)
- Saturation: How vivid the color is (0%=gray, 100%=full color)
- Lightness: How light or dark (0%=black, 50%=pure color, 100%=white)
Best for:
- Creating color variations (change lightness for hover states)
- Building color palettes (keep hue constant, vary saturation/lightness)
- Accessible design (lightness directly maps to contrast)
- CSS custom properties and theming
Example — creating a button hover state:
:root {
--brand-hue: 8;
--brand-sat: 77%;
}
.button {
background: hsl(var(--brand-hue), var(--brand-sat), 61%);
}
.button:hover {
background: hsl(var(--brand-hue), var(--brand-sat), 51%);
}
Darkening by reducing lightness is natural in HSL. Doing the same in RGB or Hex requires calculating new values for all three channels.
Which Format When?
| Situation | Use | Why | |---|---|---| | Writing CSS | Hex or HSL | Both widely supported; HSL better for theming | | Design system tokens | Hex | Universal, tool-agnostic | | Creating color scales | HSL | Vary lightness/saturation intuitively | | Canvas/image processing | RGB | Maps to pixel data directly | | Sharing with designers | Hex | Everyone understands it | | Dark mode theming | HSL | Flip lightness values systematically | | Checking contrast | HSL | Lightness difference approximates contrast |
Modern CSS: oklch and oklab
CSS now supports oklch() and oklab() — perceptually uniform color spaces where equal numeric changes produce equal perceived changes. In HSL, changing lightness by 10% looks different for different hues. In OKLCH, it looks consistent.
/* Perceptually uniform — same perceived lightness change */
.light { color: oklch(70% 0.15 30); }
.dark { color: oklch(40% 0.15 30); }
OKLCH is the future of CSS color, but browser support is still catching up. For now, HSL remains the practical choice.
Building Color Palettes
A systematic approach to palette creation:
- Pick a base hue (your brand color)
- Create a lightness scale: 50, 100, 200... 900 using HSL with fixed hue and saturation
- Add complementary hues: Rotate hue by 180° for complement, 120° for triadic
- Test for accessibility: Ensure text/background combinations meet WCAG contrast ratios
ToolFlip's color palette generator automates this process. For gradients, the CSS gradient generator creates smooth transitions between colors with live preview.
Practical Tips
Avoid pure black text on pure white. #1A1918 on #F5F5F0 is easier on the eyes than #000000 on #FFFFFF. Most professional designs use near-black on near-white.
Test colors in context. A color that looks perfect in a picker might clash with your layout. Always test in the actual interface.
Use relative color syntax in CSS for hover/active states instead of hard-coding variants:
.button {
--bg: hsl(8, 77%, 61%);
background: var(--bg);
}
.button:hover {
background: hsl(from var(--bg) h s calc(l - 10%));
}
Name colors semantically, not by appearance. Use --color-primary instead of --coral. When your brand color changes, you will not need to rename everything.
Color is one of the most impactful design decisions. Understanding the notation helps you make deliberate choices instead of guessing until something looks right.