Colors
Prerequisites: Basic selectors
CSS accepts colors in several formats. All of these are the same orange-red:
.a { color: orangered; }
.b { color: #ff4500; }
.c { color: #f40; }
.d { color: rgb(255 69 0); }
.e { color: hsl(16 100% 50%); }
(#f40 is shorthand for #ff4400 — very close, but not identical.)
| Format | Notes |
|---|---|
| Named colors | 148 names like tomato, rebeccapurple, transparent, plus currentColor |
Hex #rrggbb |
Red, green, blue in hexadecimal (00–ff); #rgb short form; #rrggbbaa adds alpha |
rgb() |
Red, green, blue as 0–255 (or percentages) |
hsl() |
Hue (0–360 degrees on the color wheel), saturation, lightness |
oklch() |
Perceptual lightness, chroma, hue — best for building palettes (Level 3) |
Transparency
Add alpha after a slash, from 0 (transparent) to 1 (opaque), or as a percentage:
.overlay { background: rgb(0 0 0 / 50%); }
.tint { background: hsl(210 80% 50% / 0.15); }
.glass { background: #ffffff80; }
You'll also see the older comma syntax, rgba(0, 0, 0, 0.5) — it still
works everywhere. opacity: 0.5 is different: it fades the whole
element, including its text and children.
What the browser stores
<style>
.a { color: orangered; }
.b { color: #f40; }
.c { color: hsl(16 100% 50%); }
.d { color: rgb(0 0 0 / 50%); }
.e { color: #ff450080; }
.f { color: teal; border: 2px solid currentColor; }
</style>
<p class="a">a</p><p class="b">b</p><p class="c">c</p>
<p class="d">d</p><p class="e">e</p><p class="f">f</p>
<script>
for (const p of document.querySelectorAll("p")) {
const s = getComputedStyle(p);
console.log(p.className, s.color, p.className === "f" ? s.borderTopColor : "");
}
</script>
a rgb(255, 69, 0)
b rgb(255, 68, 0)
c rgb(255, 68, 0)
d rgba(0, 0, 0, 0.5)
e rgba(255, 69, 0, 0.5)
f rgb(0, 128, 128) rgb(0, 128, 128)
hsl(16 100% 50%)is exactlyrgb(255, 68, 0)— within one step oforangered.currentColormeans "this element'scolor", so the border follows the text color automatically. It's the default forborder-colortoo.
Why HSL is handy
Keep the hue, change lightness for shades:
:root {
--brand: hsl(210 80% 45%);
--brand-light: hsl(210 80% 92%);
--brand-dark: hsl(210 80% 25%);
}
(--brand is a custom property, used with var(--brand) —
Level 2.)
Contrast
Text needs enough contrast with its background to be readable. WCAG asks for a ratio of at least 4.5:1 for normal text and 3:1 for large text. Light gray on white is the most common failure. DevTools shows the ratio when you click a color swatch in the Styles panel.
Our Color Picker, HEX to RGB, and RGB to HEX tools convert between formats.
Practice
Write a rule for .alert with dark red text on a very light red
background, and a 1-pixel border in the text color at 40% opacity.
Show solution
.alert {
color: hsl(0 70% 30%);
background: hsl(0 100% 96%);
border: 1px solid hsl(0 70% 30% / 40%);
}