Complete Guide to Color Codes: Hex, RGB, HSL, and HSV Explained
1. Why Color Codes Matter
Every pixel on a screen is a combination of red, green, and blue light. Color codes are the precise, machine-readable instructions that tell a browser, image editor, or design tool exactly how much of each component to emit. Without a shared notation, two designers working on the same brand would produce subtly different shades; a developer's implementation would drift from the mockup; and automated tools could not compare, validate, or convert colors programmatically.
The web supports multiple color code formats — hex, RGB, HSL, and HSV — each representing the same underlying color space but optimized for different use cases. Hex is compact and universally recognized in HTML and CSS. RGB maps directly to screen hardware. HSL and HSV organize colors in ways that match human perception, making them easier to reason about when building palettes or adjusting brightness. Understanding all four formats — and when to use each — is a foundational skill for anyone working with web design, CSS, or digital graphics.
2. Hexadecimal Color Codes
Hexadecimal (hex) color codes express RGB values using base-16 notation. The format is #RRGGBB, where RR, GG, and BB are two-digit hex pairs representing red, green, and blue channel intensities from 00 (0 decimal, no intensity) to FF (255 decimal, full intensity). The leading # is required in HTML and CSS.
Each hex pair encodes 256 possible values (0–255), giving the full RGB color space 256 × 256 × 256 = 16,777,216 distinct colors. The hex notation is case-insensitive — #FF6347 and #ff6347 are identical — though most style guides prefer uppercase for consistency.
Shorthand Hex
When each channel pair contains identical digits, you can use a three-character shorthand: #RGB. The browser expands each digit by doubling it. So #F63 expands to #FF6633. Shorthand only works when both digits of each channel are equal — #1A2B3C cannot be shortened. Common examples include #FFF (white), #000 (black), and #0F0 (pure green).
Eight-Character Hex with Alpha
CSS supports an eight-character hex format — #RRGGBBAA — where the final two digits specify the alpha (opacity) channel on the same 00–FF scale. #FF634700 is fully transparent tomato red; #FF6347FF is fully opaque. The four-character shorthand #RGBA also works following the same doubling rule. Browser support for 8-digit hex is universal in modern browsers.
Common Hex Color Examples
| Color Name | Hex Code | Description |
|---|---|---|
| Pure White | #FFFFFF |
All channels at maximum; maximum brightness |
| Pure Black | #000000 |
All channels at zero; no light emitted |
| Pure Red | #FF0000 |
Red channel full, green and blue zero |
| Pure Green | #00FF00 |
Green channel full, red and blue zero |
| Pure Blue | #0000FF |
Blue channel full, red and green zero |
| Tomato | #FF6347 |
Warm red-orange; a common UI accent color |
| Dodger Blue | #1E90FF |
Bright, saturated blue; link and CTA color |
| Slate Gray | #708090 |
Cool-toned neutral; common for muted text |
Validate and Explore Hex Colors Instantly
The SnapUtils Hex Color Validator checks any hex code for format validity, shows a live preview, and converts to RGB and HSL automatically. No sign-up required.
Open Hex Color Validator3. RGB Color Model
RGB (Red, Green, Blue) is the additive color model used by all screens. It works by mixing light: full red plus full green produces yellow; full red plus full blue produces magenta; full green plus full blue produces cyan; all three at maximum produce white. The model is called "additive" because adding more light moves toward white, the opposite of subtractive models like CMYK used in print.
CSS syntax: rgb(red, green, blue) where each value is an integer from 0 to 255. Fractional values are not permitted in the legacy syntax. A modern alternative uses space separation without commas: rgb(255 99 71), supported in all current browsers.
RGBA — RGB with Alpha
The rgba() function adds a fourth parameter for alpha transparency, expressed as a decimal from 0 (fully transparent) to 1 (fully opaque). rgba(255, 99, 71, 0.5) is 50% transparent tomato red. The modern equivalent is rgb(255 99 71 / 50%) using a forward-slash separator. Both syntaxes produce identical results.
Practical RGB Examples
/* Solid colors */
color: rgb(0, 0, 0); /* Black */
color: rgb(255, 255, 255); /* White */
color: rgb(255, 99, 71); /* Tomato */
color: rgb(30, 144, 255); /* Dodger Blue */
/* Transparent colors */
background: rgba(0, 0, 0, 0.5); /* 50% black overlay */
background: rgba(30, 144, 255, 0.15); /* Subtle blue tint */
/* Modern space-separated syntax (CSS Color Level 4) */
color: rgb(255 99 71 / 80%);
RGB is the natural choice when you are writing JavaScript that reads or manipulates color values from the DOM, since getComputedStyle() returns RGB values and integer arithmetic on channel values is straightforward.
4. HSL Color Model
HSL stands for Hue, Saturation, and Lightness. Unlike RGB, which describes color as a mixture of light sources, HSL describes color in terms closer to human perception. This makes HSL dramatically more useful when you want to create color variations — tints, shades, or desaturated versions — directly in CSS without a design tool.
CSS syntax: hsl(hue, saturation%, lightness%). All three values have distinct, meaningful ranges:
- Hue — a degree on the color wheel from 0 to 360. 0° and 360° are both red; 120° is green; 240° is blue. Intermediate values produce the full spectrum in between.
- Saturation — a percentage from 0% to 100%. At 0%, any hue becomes a neutral gray; at 100%, the color is fully vivid. Reducing saturation is how you create muted or pastel variants.
- Lightness — a percentage from 0% to 100%. At 0%, the color is always black; at 100%, always white; at 50%, the color is at its purest intensity for the given hue.
Why HSL Is Easier for Designers
Consider creating a hover state that is slightly lighter than a button's base color. In RGB, you would need to calculate how much to increase all three channels. In HSL, you increase the lightness by 5–10 percentage points. Want a disabled state that looks washed out? Drop saturation to 20%. Want the same color at a different brightness for a card background? Adjust lightness. The numbers map to perceivable changes, making HSL the most design-friendly format for writing CSS by hand.
HSL also enables palette generation from a single hue. Store the hue as a CSS variable and derive an entire scale by varying lightness and saturation:
:root {
--hue: 240; /* Blue */
}
.bg-lightest { background: hsl(var(--hue), 100%, 95%); }
.bg-light { background: hsl(var(--hue), 80%, 85%); }
.base-color { background: hsl(var(--hue), 100%, 50%); }
.bg-dark { background: hsl(var(--hue), 80%, 30%); }
.bg-darkest { background: hsl(var(--hue), 60%, 15%); }
Changing --hue to any value instantly re-themes the entire set of shades while preserving their tonal relationships. This technique powers most modern CSS design tokens and component library theming systems.
HSLA — HSL with Alpha
Like RGB, HSL supports an alpha channel via hsla(hue, saturation%, lightness%, alpha). The modern CSS Color Level 4 syntax uses a forward slash: hsl(240 100% 50% / 0.5). Both forms are widely supported.
5. HSV / HSB Color Model
HSV (Hue, Saturation, Value) — also called HSB (Hue, Saturation, Brightness) — uses the same hue axis as HSL but models color intensity differently. Understanding the distinction matters when you work with design tools, since most color pickers use HSV internally.
- Hue — identical to HSL: 0–360 degrees around the color wheel.
- Saturation — in HSV, saturation represents the ratio of the hue to white. At 0%, the color is white (all channels equal at the current value level). At 100%, the color is the pure hue with no white added.
- Value / Brightness — controls the amount of light in the color. At 0%, the result is always black regardless of hue and saturation. At 100%, the color is at full brightness — but it is not white unless saturation is also 0%.
HSL vs HSV: The Key Difference
In HSL, white is reached when lightness = 100% (regardless of saturation or hue). In HSV, white is reached when value = 100% AND saturation = 0%. This means HSV's saturation-value plane forms a triangle from black (value=0) through the pure hue (value=100%, saturation=100%) to white (value=100%, saturation=0%). HSL's model is biconal — lightness 50% is the midpoint, with pure white and pure black at opposite poles.
HSV is not directly supported as a CSS function, so you cannot write hsv() in a stylesheet. However, it is the underlying model for most GUI color pickers (including those in Figma, Photoshop, and browser DevTools), which is why understanding it matters even though you will always convert to hex, RGB, or HSL before writing CSS.
6. Color Code Comparison Table
| Format | Value Range | Native CSS Support | Primary Use Case |
|---|---|---|---|
#RRGGBB Hex |
00–FF per channel | All browsers (CSS1+) | Compact color values in HTML, CSS, design tools |
#RRGGBBAA Hex Alpha |
00–FF per channel + alpha | All modern browsers (CSS4) | Transparent colors in a single token |
rgb() |
0–255 integers per channel | All browsers (CSS1+) | Programmatic color manipulation in JS |
rgba() |
0–255 + alpha 0–1 | All browsers (CSS3+) | Semi-transparent overlays, shadows, tints |
hsl() |
0–360° hue, 0–100% sat/light | All browsers (CSS3+) | CSS theming, palette generation, hover states |
hsla() |
HSL + alpha 0–1 | All browsers (CSS3+) | HSL colors with transparency |
| HSV / HSB | 0–360° hue, 0–100% sat/value | Not supported in CSS | Color picker UIs, design tool internals |
| CSS Named Colors | 140+ keyword names | All browsers (CSS1+) | Readable prototyping, well-known standard colors |
7. Converting Between Formats
Hex to RGB
Split the six hex digits into three pairs and convert each pair from base-16 to base-10. The formula for a single pair XY is: (X × 16) + Y, where both X and Y are their decimal digit equivalents (A=10, B=11, C=12, D=13, E=14, F=15).
Example: #FF6347 → rgb(255, 99, 71)
FF → (15 × 16) + 15 = 255 (Red)
63 → (6 × 16) + 3 = 99 (Green)
47 → (4 × 16) + 7 = 71 (Blue)
// JavaScript implementation
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
RGB to Hex
Convert each decimal integer (0–255) to a two-digit hexadecimal string, padding with a leading zero if necessary, then concatenate with a # prefix.
Example: rgb(255, 99, 71) → #FF6347
255 → FF
99 → 63
71 → 47
// JavaScript implementation
function rgbToHex(r, g, b) {
return '#' + [r, g, b]
.map(v => v.toString(16).padStart(2, '0').toUpperCase())
.join('');
}
RGB to HSL
The conversion requires normalizing the RGB values to a 0–1 scale, identifying the maximum and minimum channel values, and computing each HSL component from those. The full algorithm:
// Normalize to 0–1
r' = r / 255, g' = g / 255, b' = b / 255
Cmax = max(r', g', b')
Cmin = min(r', g', b')
Δ = Cmax - Cmin
// Lightness
L = (Cmax + Cmin) / 2
// Saturation
if Δ = 0:
S = 0
else:
S = Δ / (1 - |2L - 1|)
// Hue (degrees)
if Δ = 0:
H = 0
else if Cmax = r':
H = 60 × (((g' - b') / Δ) mod 6)
else if Cmax = g':
H = 60 × ((b' - r') / Δ + 2)
else: // Cmax = b'
H = 60 × ((r' - g') / Δ + 4)
// Example: rgb(255, 99, 71) → hsl(9°, 100%, 64%)
r'=1.0, g'=0.388, b'=0.278
Cmax=1.0 (red), Cmin=0.278, Δ=0.722
L = (1.0 + 0.278) / 2 = 0.639 → 64%
S = 0.722 / (1 - |2(0.639) - 1|) = 0.722 / 0.722 = 1.0 → 100%
H = 60 × ((0.388 - 0.278) / 0.722 mod 6) = 60 × 0.152 ≈ 9°
HSL to RGB
The reverse conversion uses intermediate values C (chroma), X (second-largest component), and m (match value to lift all channels to the correct lightness):
C = (1 - |2L - 1|) × S
X = C × (1 - |(H / 60) mod 2 - 1|)
m = L - C / 2
// Map H sector to (R1, G1, B1) pre-shift values:
H in [0, 60): (R1,G1,B1) = (C, X, 0)
H in [60, 120): (R1,G1,B1) = (X, C, 0)
H in [120,180): (R1,G1,B1) = (0, C, X)
H in [180,240): (R1,G1,B1) = (0, X, C)
H in [240,300): (R1,G1,B1) = (X, 0, C)
H in [300,360): (R1,G1,B1) = (C, 0, X)
// Final RGB (0–255):
R = (R1 + m) × 255
G = (G1 + m) × 255
B = (B1 + m) × 255
In practice, you rarely need to implement these conversions manually. Browser DevTools, design tools, and libraries like chroma.js or tinycolor2 handle them. But understanding the underlying math helps you debug unexpected results when colors shift during a conversion pipeline.
8. CSS Color Names
CSS defines 140 named colors — from aliceblue and antiquewhite to yellowgreen — that map to specific hex values. Every named color has an exact hex equivalent: tomato is #FF6347, rebeccapurple is #663399, deepskyblue is #00BFFF.
Named colors are useful for rapid prototyping and for well-known standard colors where the name is more readable than the hex code. Using color: red in a design system is acceptable for placeholder states; using it in production CSS is usually a mistake because red (#FF0000) is saturated to the point of being visually harsh and rarely matches brand specifications.
The most commonly used named colors in production CSS tend to be the neutral extremes — white, black, transparent — and the color keyword currentColor, which inherits the element's computed color value. currentColor is particularly useful for SVG fills and icon colors that should match adjacent text.
- Neutrals:
white,black,gray,silver,darkgray,lightgray - Common brand palette anchors:
navy,teal,olive,maroon,purple - Special keywords:
transparent(equivalent torgba(0,0,0,0)),currentColor,inherit
9. Choosing the Right Format for Your Project
The choice of color format is rarely critical from a technical standpoint — browsers accept all formats and convert internally. The difference is ergonomic: which format lets you write and maintain CSS most efficiently for your context?
Use Hex When
- You are working with static design tokens or a design system where colors are defined by brand and stored as constants
- You are copying values from a design tool (Figma, Sketch, Adobe XD all display hex by default)
- You need maximum compatibility including older tools that only accept hex syntax
- You want a compact single-token representation without function call syntax
Use RGB When
- You are manipulating color channel values in JavaScript (e.g., darkening a color by subtracting from all channels)
- You need to pass color values to a canvas context (
CanvasRenderingContext2Daccepts any CSS color string, but many operations return RGB) - You are working with color values returned from
getComputedStyle(), which always returnsrgb()orrgba()
Use HSL When
- You are generating color scales or palettes from a single base hue using CSS custom properties
- You are writing hover, active, or focus states that should be lighter or darker variants of the base color
- You want to define a dark mode by adjusting lightness without changing hue
- You are building a design token system where tonal relationships should be readable in the source code
Decision Guide
| Context | Recommended Format |
|---|---|
| Static brand color tokens | Hex (#RRGGBB) |
| CSS custom properties for theming | HSL components (hsl(var(--h) var(--s) var(--l))) |
| Transparent overlays | rgba() or hex with alpha (#RRGGBBAA) |
| JavaScript color manipulation | RGB integers, convert to hex for output |
| Tints and shades in CSS | HSL with varying lightness |
| Prototyping / placeholder colors | CSS named colors |
Generate Complete Color Palettes in Seconds
The SnapUtils Color Palette Generator creates harmonious palettes from any base color — with complementary, triadic, and analogous schemes — and exports hex, RGB, and HSL values.
Open Color Palette Generator10. Color Accessibility
Color codes are not just aesthetic — they have measurable accessibility implications. The WCAG (Web Content Accessibility Guidelines) 2.1 standard defines minimum contrast ratios between foreground and background colors that must be met for text to be readable by users with low vision or color blindness.
Contrast Ratios
The WCAG contrast ratio formula compares the relative luminance of two colors on a scale from 1:1 (identical) to 21:1 (pure black on pure white). The minimum requirements at Level AA — the most commonly mandated standard — are:
- Normal text (below 18pt / 24px, or below 14pt / 18.67px bold): minimum 4.5:1
- Large text (18pt or larger, or 14pt bold or larger): minimum 3:1
- UI components and graphical objects (form borders, icons, charts): minimum 3:1
Level AAA raises the bar to 7:1 for normal text and 4.5:1 for large text. While AAA is not required for most compliance contexts, it represents best practice for highly readable interfaces.
Color Blindness Considerations
Approximately 8% of men and 0.5% of women have some form of color vision deficiency. The most common type — red-green color blindness (deuteranopia and protanopia) — means users cannot reliably distinguish red from green. If your interface uses color alone to communicate state (red for error, green for success), those users receive no information. WCAG SC 1.4.1 explicitly prohibits using color as the only visual means of conveying information. Always supplement color with icons, text labels, or patterns.
Practical Color Accessibility Checklist
- Check every text color / background color pair against the 4.5:1 threshold using a contrast checker
- Verify focus indicator colors achieve at least 3:1 against adjacent backgrounds
- Test your palette using a color blindness simulation tool (browser extensions like Colorblindly or DevTools' vision emulation)
- Never communicate error, warning, or success states with color alone — always include a text label or icon
- Check that charts, graphs, and data visualizations remain distinguishable in grayscale
Your choice of color format does not affect accessibility — a failing contrast pair fails in hex, RGB, and HSL equally. But HSL makes it easier to adjust: if a text color fails contrast, increase the lightness difference between foreground and background until it passes. The HSL lightness axis maps directly to the luminance difference that the contrast ratio measures.
11. Frequently Asked Questions
What is the difference between hex and RGB color codes?
Hex and RGB represent exactly the same information using different notation. rgb(255, 99, 71) and #FF6347 are the same color. Hex encodes each channel as two hexadecimal digits; RGB uses decimal integers. The formats are interchangeable in CSS and can be converted losslessly in either direction. The choice comes down to readability and tooling preference.
Why do designers prefer HSL over RGB?
HSL maps more closely to how humans perceive and describe color. "Make this blue 10% lighter" is a single change in HSL (increase lightness by 10 percentage points) but requires calculating proportional increases across all three RGB channels. "Create a muted version" means reducing HSL saturation; in RGB, it requires a non-obvious channel averaging operation. This intuitive relationship between HSL values and perceived color changes makes HSL the preferred format for writing CSS by hand and building theme systems.
What is the difference between HSL and HSV?
Both use a 0–360° hue axis and a 0–100% saturation axis, but they differ at the extremes. In HSL, 100% lightness is always white and 0% is always black. In HSV, 100% value with 0% saturation is white, but 100% value with 100% saturation is the pure vivid hue. HSV more closely models how physical paint pigments behave and is used internally by most GUI color pickers. CSS supports HSL natively; HSV is not a CSS color function.
Can I use HSL colors directly in CSS?
Yes. hsl() and hsla() have been supported in CSS since CSS3 and work in all modern browsers. The syntax is hsl(hue, saturation%, lightness%) or the newer space-separated form hsl(hue saturation% lightness%). They are particularly powerful in combination with CSS custom properties, allowing you to define a base hue once and derive an entire tonal scale through lightness and saturation variations.
How do I convert hex to RGB?
Split the six-character hex code into three pairs and convert each from base-16 to base-10. For #FF6347: FF = 255, 63 = 99, 47 = 71, giving rgb(255, 99, 71). In JavaScript: parseInt('FF', 16) returns 255. For shorthand hex like #F63, expand each digit to two first: #FF6633, then convert each pair.
Related articles: Hex Colors & WCAG Contrast Guide • Color Contrast Checker Guide • SVG vs PNG: Which Format Should You Use?