What is HWB?
The HWB (Hue, Whiteness, Blackness) color notation is defined in the CSS Color Module Level 4 specification and provides an intuitive way to express colors based on how much white and black are mixed with a base hue. Unlike RGB, which models colors as combinations of red, green, and blue light, HWB models colors in a way that closely mirrors how humans think about color adjustments.
The key insight behind HWB is that most color manipulations involve either lightening a color (adding white) or darkening a color (adding black). By providing direct control over these two parameters, HWB eliminates the mental gymnastics required when working with RGB or HSL color values.
The HWB Color Triangle
Imagine a color space shaped like a triangle. At one corner sits the pure, fully saturated hue. At another corner is pure white, and at the third corner is pure black. Every color in the HWB system exists somewhere inside this triangle.
- Moving toward the white corner adds lightness to your color, creating lighter tints
- Moving toward the black corner adds darkness, creating deeper shades
- Staying near the pure hue corner keeps your color rich and saturated
This triangular model makes HWB remarkably intuitive. When you want a lighter version of your brand blue, you simply move toward the white corner. When you need a more dramatic, darker variant for hover states, you move toward the black corner. The relationship is consistent and predictable, regardless of which hue you're working with.
HWB Syntax and Values
The HWB functional notation follows this format:
hwb(H W B[ / A])
Where each component serves a specific purpose in defining the final color.
Hue (H)
The hue component specifies the base color angle on the color wheel. As documented by MDN Web Docs, the hue can be specified using several unit types:
/* Using degrees - most common approach */
hwb(180deg 50% 50%); /* Cyan at medium whiteness and blackness */
hwb(0deg 0% 0%); /* Pure red */
hwb(360deg 50% 50%); /* Same as 0deg */
/* Using radians for mathematical precision */
hwb(3.14159rad 50% 50%); /* Approximately red */
/* Using turns - intuitive for fractional colors */
hwb(0.25turn 30% 20%); /* Yellow-orange */
/* Unitless numbers - interpreted as degrees */
hwb(240 50% 50%); /* Blue */
The hue angle corresponds to the same color wheel used by the HSL() function, where 0deg and 360deg represent red, 120deg represents green, and 240deg represents blue.
Whiteness (W) and Blackness (B)
The whiteness and blackness components are percentages that control how much white or black is mixed into the color:
/* No white or black - fully saturated color */
hwb(200 0% 0%);
/* Adding 40% white - lighter shade */
hwb(200 40% 0%);
/* Adding 30% black - darker shade */
hwb(200 0% 30%);
/* Adding both white and black - muted tone */
hwb(200 25% 25%);
/* Pure white */
hwb(0 100% 100%);
/* Pure black */
hwb(0 0% 100%);
When both whiteness and blackness are 0%, the color is fully saturated. As you increase either value, the color becomes more desaturated. When the sum of whiteness and blackness reaches or exceeds 100%, the result is a shade of gray regardless of the hue value.
Alpha (A) - Optional
The alpha component specifies the color's opacity, following the same pattern as other CSS color functions:
/* Semi-transparent with number */
hwb(210 0% 0% / 0.5);
/* Semi-transparent with percentage */
hwb(120 0% 0% / 50%);
/* Fully transparent */
hwb(0 0% 0% / 0);
/* Opaque */
hwb(0 0% 0% / 1);
Practical Examples
Basic Color Definitions
/* Pure red - fully saturated, no white or black added */
.pure-red {
background-color: hwb(0 0% 0%);
}
/* Red with 50% white added - lighter tint */
.light-red {
background-color: hwb(0 50% 0%);
}
/* Red with 30% black added - darker shade */
.dark-red {
background-color: hwb(0 0% 30%);
}
/* Desaturated red - 30% white and 30% black */
.muted-red {
background-color: hwb(0 30% 30%);
}
/* Near-white red - mostly white with hint of red */
.pale-red {
background-color: hwb(0 90% 5%);
}
/* Near-black red - deep, dramatic shade */
.deep-red {
background-color: hwb(0 5% 85%);
}
Creating Harmonious Color Scales
One of HWB's strongest use cases is creating harmonious color scales where you need variations of the same hue at different brightness levels. This approach is essential for building scalable design systems that maintain visual consistency across your application:
:root {
--hue: 220;
/* Light tints for backgrounds and subtle accents */
--color-primary-100: hwb(var(--hue) 85% 5%);
--color-primary-200: hwb(var(--hue) 70% 10%);
--color-primary-300: hwb(var(--hue) 55% 15%);
/* Primary brand colors */
--color-primary-400: hwb(var(--hue) 40% 20%);
--color-primary-500: hwb(var(--hue) 25% 25%);
/* Darker shades for hover states and emphasis */
--color-primary-600: hwb(var(--hue) 10% 30%);
--color-primary-700: hwb(var(--hue) 5% 45%);
--color-primary-800: hwb(var(--hue) 0% 60%);
--color-primary-900: hwb(var(--hue) 0% 75%);
}
/* Using the scale in your components */
.btn-primary {
background-color: var(--color-primary-500);
color: white;
}
.btn-primary:hover {
background-color: var(--color-primary-600);
}
.btn-primary:active {
background-color: var(--color-primary-700);
}
.card {
background-color: var(--color-primary-100);
border: 1px solid var(--color-primary-200);
}
Interactive Color States
HWB excels at creating predictable interactive color states for front-end development projects:
.button {
/* Base state - fully saturated brand color */
background-color: hwb(var(--brand-hue) 0% 0%);
color: white;
}
.button:hover {
/* Lighten on hover by adding whiteness */
background-color: hwb(var(--brand-hue) 15% 0%);
}
.button:active {
/* Darken on click by adding blackness */
background-color: hwb(var(--brand-hue) 0% 15%);
}
.button:disabled {
/* Desaturate for disabled state */
background-color: hwb(var(--brand-hue) 50% 50%);
opacity: 0.5;
}
HWB vs HSL: When to Use Each
Both HWB and HSL are cylindrical color models that separate hue from saturation and lightness, but they approach color manipulation differently, as noted in CSS-Tricks analysis of HWB.
Conceptual Differences
HSL (Hue, Saturation, Lightness):
- Separates color into hue (the base color), saturation (how vivid the color is), and lightness (how light or dark the color is)
- Adjusting saturation requires understanding how saturation affects color intensity
- Lightness adjustments can push colors into unnatural regions (e.g., lightness 100% is always white, regardless of hue)
- The relationship between saturation percentage and perceived intensity varies by hue
HWB (Hue, Whiteness, Blackness):
- Separates color into hue (the base color), whiteness (how much white to add), and blackness (how much black to add)
- Adding white or black has predictable effects regardless of the base hue
- More intuitive for creating tints (adding white) and shades (adding black)
- Results are more consistent across different hues
When to Choose HWB
Consider HWB when:
- Building color scales - Creating light-to-dark variations becomes straightforward
- Implementing dark mode - Simply increase whiteness to adapt colors for dark backgrounds
- Creating interactive states - Add white for lighter hover states, black for darker active states
- Working with non-designers - The white/black model is easier to explain and modify
Consider HSL when:
- Fine saturation control - When you need precise control over color intensity
- Existing HSL infrastructure - Working with tools or libraries already based on HSL
- Complex color mixing - Some advanced color operations are easier in HSL
/* Same color expressed in both notations */
.hsl-example {
/* HSL: Red at 100% saturation and 50% lightness */
background-color: hsl(0 100% 50%);
}
.hwb-example {
/* HWB: Red with no white or black added */
background-color: hwb(0 0% 0%);
}
Discover scenarios where HWB excels in real-world web development projects
Dark Mode Implementation
HWB simplifies dark mode color creation by making it easy to create appropriately darkened variants of your color palette. Simply adjust whiteness and blackness values to maintain brand recognition in low-light environments.
Accessible Color Contrast
When creating accessible color systems, HWB makes it straightforward to adjust colors until they meet WCAG contrast requirements. Tweak whiteness or blackness until text becomes legible against its background.
CSS Custom Properties
HWB works seamlessly with CSS custom properties for dynamic theming. Define a base hue and let HWB handle all the light and dark variations automatically.
Design System Color Scales
Build comprehensive color palettes with predictable light and dark variations using HWB's intuitive mixing model. Perfect for creating systematic design tokens.
1/* Complete theme example using HWB */2:root {3 /* Brand colors - fully saturated base */4 --brand-blue: hwb(215 0% 0%);5 --brand-purple: hwb(265 0% 0%);6 7 /* Light theme - increased whiteness */8 --primary: hwb(215 45% 15%);9 --primary-light: hwb(215 65% 10%);10 --primary-dark: hwb(215 30% 25%);11 12 /* Text colors */13 --text-primary: hwb(215 5% 10%);14 --text-secondary: hwb(215 15% 35%);15 --text-muted: hwb(215 30% 55%);16 17 /* Background colors */18 --bg-primary: hwb(215 98% 2%);19 --bg-secondary: hwb(215 95% 5%);20 --bg-tertiary: hwb(215 85% 10%);21}22 23@media (prefers-color-scheme: dark) {24 :root {25 /* Dark theme - adjusted for legibility */26 --primary: hwb(215 25% 40%);27 --primary-light: hwb(215 40% 30%);28 --primary-dark: hwb(215 15% 50%);29 30 /* Invert text colors for dark backgrounds */31 --text-primary: hwb(215 95% 90%);32 --text-secondary: hwb(215 85% 75%);33 --text-muted: hwb(215 70% 60%);34 35 /* Dark backgrounds */36 --bg-primary: hwb(215 5% 8%);37 --bg-secondary: hwb(215 10% 12%);38 --bg-tertiary: hwb(215 15% 18%);39 }40}Browser Compatibility
The HWB color function has excellent browser support, having been widely available since 2022 according to MDN Web Docs:
| Browser | Version | Release Date |
|---|---|---|
| Chrome | 101+ | April 2022 |
| Edge | 101+ | April 2022 |
| Firefox | 96+ | January 2022 |
| Safari | 15+ | September 2021 |
| Samsung Internet | 19.0+ | March 2022 |
With support dating back to 2021-2022, HWB is considered safe to use in production for the vast majority of modern web projects. The only users who might not see HWB colors are those on extremely outdated browsers, which typically represent a negligible percentage of web traffic.
Feature Detection
For projects that need to support older browsers (though this is rarely necessary in 2025), you can use feature detection:
@supports (background-color: hwb(0 0% 0%)) {
.element {
background-color: hwb(220 30% 20%);
color: hwb(220 95% 5%);
}
}
/* Fallback for older browsers */
@supports not (background-color: hwb(0 0% 0%)) {
.element {
background-color: #3d5a80;
color: #eef4ed;
}
}
Progressive Enhancement
Since HWB degrades gracefully (older browsers simply ignore the declaration), you can often use HWB without any fallback at all. Modern browsers will render your carefully crafted HWB colors, while older browsers will use any fallback you specified in a previous declaration or inherit from other CSS rules.
Tips and Best Practices
Start with Pure Colors
When defining a color palette, begin with fully saturated colors (0% whiteness, 0% blackness) and build variations from there. This ensures consistency across your palette:
:root {
/* Base colors - fully saturated */
--blue: hwb(210 0% 0%);
--red: hwb(0 0% 0%);
--green: hwb(120 0% 0%);
--orange: hwb(30 0% 0%);
/* Light variants - systematically add 15-25% whiteness */
--blue-light: hwb(210 20% 0%);
--red-light: hwb(0 20% 0%);
--green-light: hwb(120 20% 0%);
--orange-light: hwb(30 20% 0%);
/* Dark variants - systematically add 15-25% blackness */
--blue-dark: hwb(210 0% 20%);
--red-dark: hwb(0 0% 20%);
--green-dark: hwb(120 0% 20%);
--orange-dark: hwb(30 0% 20%);
}
Use Relative Colors for Dynamic Adjustments
CSS Color Level 5 introduces relative color syntax, which works with HWB for powerful color transformations:
.element {
/* Lighten existing color by 10% blackness */
background-color: hwb(from var(--base-color) h w calc(b + 10%));
}
.hover-effect {
/* Create hover state with 20% more whiteness */
background-color: hwb(from var(--color) h calc(w + 20%) b);
}
Combine with CSS Color Functions
HWB can be combined with other color functions like color-mix() for even more flexibility:
.mixed-color {
/* Mix HWB color with white */
background-color: color-mix(in hwb, hwb(0 0% 0%) 70%, white);
}
.tinted-background {
/* Mix HWB color with transparent to create tints */
background-color: color-mix(in hwb, hwb(200 0% 0%), white 20%);
}
Avoid Common Pitfalls
Don't exceed 100% total: When W + B exceeds 100%, colors normalize proportionally. While this can be useful for gray shades, it can cause unexpected results if you're trying to create specific tints.
Test across hues: Some hues may appear more or less saturated at the same W+B values. Always test your color scale across different hues.
Consider color blindness: HWB doesn't automatically solve accessibility issues. Always verify your color combinations meet WCAG guidelines using tools like the WebAIM Contrast Checker.
Frequently Asked Questions
Conclusion
The HWB color function provides a more intuitive way to specify and manipulate colors in CSS, especially when creating tints and shades. By directly controlling how much white or black to mix with a hue, HWB eliminates the cognitive overhead of working with RGB or HSL in many common scenarios.
Whether you're building a comprehensive design system with web development services, implementing dark mode support, or simply trying to create harmonious color palettes for your website, HWB offers a straightforward approach that aligns with how we naturally think about color.
As browser support continues to mature and CSS Color Level 5 brings even more powerful features, HWB is poised to become a staple in modern CSS development. Start incorporating HWB into your projects today, and discover how this human-friendly color notation can simplify your CSS color management.
For teams looking to level up their front-end development capabilities, mastering modern CSS color functions like HWB is an excellent step toward building more maintainable, scalable stylesheets.
Sources
- MDN Web Docs - hwb() - Official browser documentation covering HWB syntax and values
- W3C CSS Color Module Level 4 Specification - Official W3C specification for CSS colors
- Stefan Judis - hwb() a color notation for humans? - Developer perspective on HWB's intuitive design
- CSS-Tricks - Why is Nobody Using the hwb() Color Function? - Analysis of HWB adoption and use cases
- Chrome for Developers - High definition CSS color guide - Modern CSS color functions documentation