CSS Colors
Color is one of the most fundamental aspects of CSS. Modern CSS provides a rich palette of color formats — from simple named colors to advanced functional notations like oklch() and color-mix(). Understanding these options gives you precise control over the visual appearance of your designs.
Every color in CSS ultimately resolves to a numeric representation in one of several color spaces. The choice of format affects gamut, interpolation behavior in gradients and animations, and browser compatibility. This guide covers all major CSS color formats with practical examples.
| 1 | /* CSS color formats at a glance */ |
| 2 | .element { |
| 3 | color: red; /* named color */ |
| 4 | color: #FF0000; /* hex RGB */ |
| 5 | color: rgb(255, 0, 0); /* RGB functional */ |
| 6 | color: rgba(255, 0, 0, 0.5); /* RGB with alpha */ |
| 7 | color: hsl(0, 100%, 50%); /* HSL */ |
| 8 | color: hwb(0, 0%, 0%); /* HWB */ |
| 9 | color: oklch(0.6, 0.25, 0); /* OKLCH perceptually uniform */ |
| 10 | color: color-mix(in srgb, red, blue); /* color mixing */ |
CSS defines 148 named color keywords, including the 16 basic HTML colors (aqua, black, blue, fuchsia, gray, green, lime, maroon, navy, olive, purple, red, silver, teal, white, yellow) plus extended SVG/CSS colors. Named colors are the most readable format but offer the least control.
| 1 | .transparent { color: transparent; } /* fully transparent */ |
| 2 | .current-color { color: currentColor; } /* inherits from color property */ |
| 3 | .rebeccapurple { color: rebeccapurple; } /* #663399 — commemorative */ |
| 4 | |
| 5 | /* Common named colors */ |
| 6 | .primary { color: #00FF41; } |
| 7 | .warning { color: #FFB000; } |
| 8 | .error { color: #EF4444; } |
| 9 | .info { color: #3B82F6; } |
| 10 | .neutral { color: #808080; } |
| 11 | .dim { color: #525252; } |
Hexadecimal color notation is the most widely used format on the web. It represents the red, green, and blue channels as two-digit hex values (00-FF). Modern CSS supports both 6-digit RGB and 8-digit RGBA notation with an alpha channel.
| 1 | /* 6-digit hex — most common */ |
| 2 | .bright-green { color: #00FF41; } |
| 3 | .dark-bg { background: #0D0D0D; } |
| 4 | .text-light { color: #E0E0E0; } |
| 5 | .muted { color: #808080; } |
| 6 | .border { border-color: #222222; } |
| 7 | |
| 8 | /* 3-digit shorthand — only when each pair has matching digits */ |
| 9 | .short-red { color: #F00; } /* same as #FF0000 */ |
| 10 | .short-green { color: #0F0; } /* same as #00FF00 */ |
| 11 | .short-blue { color: #00F; } /* same as #0000FF */ |
| 12 | |
| 13 | /* 8-digit hex with alpha channel */ |
| 14 | .semi-transparent { |
| 15 | background: #00FF4180; /* 50% opacity green */ |
| 16 | } |
| 17 | |
| 18 | .more-transparent { |
| 19 | background: #00FF4133; /* 20% opacity green */ |
| 20 | } |
| 21 | |
| 22 | /* 4-digit hex shorthand with alpha */ |
| 23 | .short-alpha { color: #F00F; } /* #FF0000FF — but in 4-char shorthand */ |
info
The rgb() and rgba() functions define colors using the red, green, and blue color channels. Modern CSS accepts both the legacy comma-separated syntax and the newer space-separated syntax. The rgba() alias is now identical to rgb() — both accept an optional alpha parameter.
| 1 | /* Legacy comma-separated syntax */ |
| 2 | .rgb-legacy { |
| 3 | color: rgb(255, 0, 0); /* red */ |
| 4 | color: rgb(0, 255, 65); /* green */ |
| 5 | color: rgba(0, 255, 65, 0.5); /* green at 50% */ |
| 6 | } |
| 7 | |
| 8 | /* Modern space-separated syntax */ |
| 9 | .rgb-modern { |
| 10 | color: rgb(255 0 0); /* red */ |
| 11 | color: rgb(0 255 65 / 0.5); /* green at 50% opacity */ |
| 12 | color: rgb(0 255 65 / 50%); /* percentage alpha */ |
| 13 | } |
| 14 | |
| 15 | /* Percentage values */ |
| 16 | .rgb-percent { |
| 17 | color: rgb(100% 0% 0%); /* red */ |
| 18 | color: rgb(0% 100% 25.5%); /* green */ |
| 19 | } |
| 20 | |
| 21 | /* Practical terminal theme */ |
| 22 | .terminal-text { |
| 23 | color: rgb(0, 255, 65); /* #00FF41 */ |
| 24 | } |
| 25 | |
| 26 | .terminal-bg { |
| 27 | background: rgb(13, 13, 13); /* #0D0D0D */ |
| 28 | } |
| 29 | |
| 30 | .terminal-muted { |
| 31 | color: rgba(160, 160, 160, 0.8); /* #A0A0A0 at 80% */ |
HSL (Hue, Saturation, Lightness) is an intuitive color model. Hue is an angle on the color wheel (0-360deg), saturation is the intensity (0-100%), and lightness is the brightness (0-100% where 50% is pure color). This format makes it easy to create color palettes by adjusting one dimension at a time.
| 1 | /* HSL basics */ |
| 2 | .red { color: hsl(0, 100%, 50%); } /* pure red */ |
| 3 | .green { color: hsl(120, 100%, 50%); } /* pure green */ |
| 4 | .blue { color: hsl(240, 100%, 50%); } /* pure blue */ |
| 5 | |
| 6 | /* Terminal palette in HSL */ |
| 7 | .terminal-green { color: hsl(130, 100%, 50%); } /* #00FF41 */ |
| 8 | .terminal-yellow { color: hsl(40, 100%, 50%); } /* #FFB000 */ |
| 9 | .terminal-text { color: hsl(0, 0%, 88%); } /* #E0E0E0 */ |
| 10 | .terminal-muted { color: hsl(0, 0%, 50%); } /* #808080 */ |
| 11 | .terminal-bg { background: hsl(0, 0%, 5%); } /* #0D0D0D */ |
| 12 | |
| 13 | /* With alpha */ |
| 14 | .semi-green { color: hsla(130, 100%, 50%, 0.5); } |
| 15 | |
| 16 | /* Modern space-separated with slash alpha */ |
| 17 | .modern-hsl { color: hsl(130 100% 50% / 0.5); } |
| 18 | |
| 19 | /* Color wheel — shift hue for variants */ |
| 20 | .base { background: hsl(200, 80%, 50%); } |
| 21 | .lighter { background: hsl(200, 80%, 70%); } /* same hue, lighter */ |
| 22 | .darker { background: hsl(200, 80%, 30%); } /* same hue, darker */ |
| 23 | .grayish { background: hsl(200, 20%, 50%); } /* same hue, desaturated */ |
pro tip
HWB is a more intuitive alternative to HSL. Instead of saturation and lightness, you specify whiteness (amount of white mixed in) and blackness (amount of black mixed in). The result is a color that feels natural to describe — like "red with 20% white and 10% black."
| 1 | /* HWB syntax: hwb(hue whiteness% blackness% / alpha) */ |
| 2 | .pure { color: hwb(130 0% 0%); } /* pure green, no white, no black */ |
| 3 | .tinted { color: hwb(130 50% 0%); } /* green + 50% white = pastel */ |
| 4 | .shaded { color: hwb(130 0% 50%); } /* green + 50% black = dark */ |
| 5 | .muted { color: hwb(130 30% 30%); } /* green + both = desaturated */ |
| 6 | |
| 7 | /* Terminal green variations */ |
| 8 | .terminal-bright { background: hwb(130 0% 0%); } /* #00FF41 */ |
| 9 | .terminal-dark { background: hwb(130 0% 80%); } /* dark green bg */ |
| 10 | .terminal-pastel { background: hwb(130 40% 0%); } /* light green tint */ |
| 11 | |
| 12 | /* With alpha */ |
| 13 | .transparent-green { background: hwb(130 0% 0% / 0.5); } |
The color-mix() function blends two colors in a given color space. This is incredibly useful for theming, hover states, and generating color variations without preprocessor variables.
| 1 | /* color-mix(in <colorspace>, color1, color2) */ |
| 2 | |
| 3 | /* Mix in sRGB — most compatible */ |
| 4 | .hover-brighten { |
| 5 | background: color-mix(in srgb, #00FF41, white 25%); |
| 6 | } |
| 7 | |
| 8 | /* Mix in OKLCH — perceptually smooth */ |
| 9 | .smooth-blend { |
| 10 | background: color-mix(in oklch, #00FF41, #3B82F6); |
| 11 | } |
| 12 | |
| 13 | /* Different proportions */ |
| 14 | .equal-parts { color: color-mix(in srgb, red, blue); } |
| 15 | .more-red { color: color-mix(in srgb, red 75%, blue); } |
| 16 | .more-blue { color: color-mix(in srgb, red 25%, blue); } |
| 17 | |
| 18 | /* Practical terminal use */ |
| 19 | .terminal-hover { background: color-mix(in srgb, #00FF41, #0D0D0D 80%); } |
| 20 | .terminal-active { background: color-mix(in srgb, #00FF41, #0D0D0D 60%); } |
| 21 | .terminal-border { border-color: color-mix(in srgb, #00FF41, transparent 85%); } |
| 22 | |
| 23 | /* Color space options */ |
| 24 | .srgb { background: color-mix(in srgb, red, blue); } |
| 25 | .srgb-linear { background: color-mix(in srgb-linear, red, blue); } |
| 26 | .lab { background: color-mix(in lab, red, blue); } |
| 27 | .oklch { background: color-mix(in oklch, red, blue); } |
The color() function allows you to specify colors in any ICC color profile, including Display P3 (wider gamut than sRGB), Rec2020, and custom profiles. This unlocks access to over 50% more visible colors than sRGB on modern displays.
| 1 | /* color() function — access wider gamut color spaces */ |
| 2 | |
| 3 | /* Display P3 — wider gamut (Apple devices, modern displays) */ |
| 4 | .p3-bright-green { |
| 5 | color: color(display-p3 0 1 0.25); |
| 6 | } |
| 7 | |
| 8 | /* sRGB through color() */ |
| 9 | .srgb-color { |
| 10 | color: color(srgb 0 1 0.25); |
| 11 | } |
| 12 | |
| 13 | /* Rec2020 — ultra wide gamut (4K/HDR broadcasts) */ |
| 14 | .rec2020-red { |
| 15 | color: color(rec2020 0.9 0.1 0.1); |
| 16 | } |
| 17 | |
| 18 | /* Linear sRGB — physically correct */ |
| 19 | .linear-green { |
| 20 | color: color(srgb-linear 0 1 0.25); |
| 21 | } |
| 22 | |
| 23 | /* Profile support */ |
| 24 | .profile { color: color(display-p3 0 1 0.2); } |
| 25 | .hdr { color: color(rec2020 0.5 0.9 0.2); } |
| 26 | .xyz { color: color(xyz-d50 0.5 0.8 0.3); } |
| 27 | .xyz-d65 { color: color(xyz-d65 0.5 0.8 0.3); } |
| 28 | |
| 29 | /* Fallback pattern — hex first, then P3 */ |
| 30 | .enhanced-color { |
| 31 | color: #00FF41; |
| 32 | color: color(display-p3 0 1 0.25); |
| 33 | } |
warning
The currentColor keyword represents the computed value of the color property. It is inherited automatically and can be used anywhere a color value is accepted — enabling components to inherit text color for borders, shadows, backgrounds, and SVG fills.
| 1 | /* currentColor inherits the text color */ |
| 2 | .button { |
| 3 | color: #00FF41; |
| 4 | border: 2px solid currentColor; /* green border matching text */ |
| 5 | background: transparent; |
| 6 | } |
| 7 | |
| 8 | .button:hover { |
| 9 | background: currentColor; /* green background on hover */ |
| 10 | color: #0D0D0D; /* dark text on green bg */ |
| 11 | } |
| 12 | |
| 13 | /* SVG icon inheritance */ |
| 14 | .icon { |
| 15 | fill: currentColor; /* icon matches surrounding text */ |
| 16 | stroke: currentColor; |
| 17 | } |
| 18 | |
| 19 | /* Utility: color-sensitive separator */ |
| 20 | .separator { |
| 21 | border-color: currentColor; |
| 22 | opacity: 0.2; |
| 23 | } |
| 24 | |
| 25 | /* Practical: theme-adapting component */ |
| 26 | .themeable { |
| 27 | color: #00FF41; |
| 28 | box-shadow: 0 0 10px currentColor; /* glow matches text color */ |
| 29 | } |
| 30 | |
| 31 | /* Cascade example */ |
| 32 | .parent { |
| 33 | color: #00FF41; |
| 34 | } |
| 35 | |
| 36 | .child { |
| 37 | border: 1px solid currentColor; /* inherits green from parent */ |
| 38 | background: color-mix(in srgb, currentColor 10%, transparent); |
| 39 | } |
WCAG (Web Content Accessibility Guidelines) defines minimum contrast ratios for text and interactive elements. The contrast ratio is calculated by comparing the relative luminance of the foreground and background colors. Conformance levels range from AA (4.5:1 for normal text) to AAA (7:1 for normal text).
| 1 | /* WCAG contrast ratio requirements */ |
| 2 | /* Normal text (< 18pt / < 14pt bold) */ |
| 3 | .normal-text-aa { /* 4.5:1 minimum */ } |
| 4 | .normal-text-aaa { /* 7:1 minimum */ } |
| 5 | |
| 6 | /* Large text (>= 18pt / >= 14pt bold) */ |
| 7 | .large-text-aa { /* 3:1 minimum */ } |
| 8 | .large-text-aaa { /* 4.5:1 minimum */ } |
| 9 | |
| 10 | /* Our terminal theme — verified AA */ |
| 11 | .terminal-text-on-bg { |
| 12 | color: #E0E0E0; /* foreground */ |
| 13 | background: #0D0D0D; /* background */ |
| 14 | /* contrast ratio ~15:1 — exceeds AAA */ |
| 15 | } |
| 16 | |
| 17 | .terminal-green-on-bg { |
| 18 | color: #00FF41; /* foreground */ |
| 19 | background: #0D0D0D; /* background */ |
| 20 | /* contrast ratio ~10:1 — exceeds AAA */ |
| 21 | } |
| 22 | |
| 23 | /* Using contrast-color() in future CSS */ |
| 24 | /* |
| 25 | .adaptive-text { |
| 26 | color: contrast-color(#0D0D0D); |
| 27 | } |
| 28 | */ |
| 29 | |
| 30 | /* Practical: ensure accessible contrast */ |
| 31 | .accessibility-check { |
| 32 | /* Avoid low-contrast combinations */ |
| 33 | /* #808080 on #0D0D0D = ~3.8:1 — fails AA for small text */ |
| 34 | /* #A0A0A0 on #0D0D0D = ~5.2:1 — passes AA for all text */ |
| 35 | color: #A0A0A0; |
| 36 | background: #0D0D0D; |
| 37 | } |
| 38 | |
| 39 | /* Color contrast with transparency */ |
| 40 | .transparent-contrast { |
| 41 | /* Transparent overlays reduce contrast — test carefully */ |
| 42 | color: rgba(224, 224, 224, 0.8); |
| 43 | background: #0D0D0D; |
| 44 | } |
| Level | Normal Text | Large Text | UI Components |
|---|---|---|---|
| AA | 4.5:1 | 3:1 | 3:1 |
| AAA | 7:1 | 4.5:1 | — |
best practice
pro tip