Introduction to CSS Color
CSS has come a long way from its early days of basic color keywords and hexadecimal notation. What began as a simple system for specifying colors using names like "red" and "blue," or three-component RGB values, has evolved into a sophisticated color manipulation framework that gives developers unprecedented control over how colors are defined, modified, and mixed directly in the browser.
The journey of CSS color reflects the evolution of web display capabilities. Early monitors were limited in color depth, and CSS colors were constrained by those hardware limitations. As displays improved, CSS expanded to support more color formats and eventually introduced perceptual color spaces that align more closely with human vision. Today, we have access to tools that allow us to modify colors dynamically, mix two colors together mathematically, and even create entire color schemes from a single base color using pure CSS.
Understanding modern CSS color is essential for creating maintainable design systems, implementing dark mode themes, and building interfaces that adapt intelligently to user preferences and accessibility requirements. When combined with SEO best practices, well-structured color systems also contribute to better user engagement and accessibility scores.
This guide covers everything from the foundational named colors and hex notation to advanced features like relative color syntax, OKLCH color spaces, color-mix(), and automatic theme switching with light-dark(). Whether you're building a simple website or a complex AI-powered application, these techniques will give you precise control over every pixel's appearance.
Named Colors and Keywords
Standard Named Colors
CSS provides over 140 named colors that you can use directly without needing to remember hexadecimal or RGB values. These include standard primary and secondary colors like red, blue, and orange, as well as more specific shades like cornflowerblue, lightseagreen, and rebeccapurple. Named colors use the sRGB color space and are case-insensitive, making them easy to work with.
Named colors are particularly useful for quick prototyping, documentation, and situations where exact color values don't need to be precisely controlled. They're also valuable for making code more readable - color: firebrick immediately communicates the intent more clearly than color: #b22222 for many developers working on web development projects.
Special Color Keywords
Beyond named colors, CSS includes several special keywords that serve specific purposes. The transparent keyword creates a fully transparent color, equivalent to rgba(0, 0, 0, 0), which is useful for creating invisible borders, backgrounds that let content show through, and layered visual effects.
The currentColor keyword takes on the value of the element's color property, making it incredibly useful for creating components where borders, icons, or other elements should automatically match the text color. This is especially valuable in icon systems and flexible UI components built with modern CSS techniques.
System Color Keywords
System color keywords like accentcolortext and buttonface reflect the default color choices made by the user's operating system, browser, or device settings. These allow developers to create interfaces that blend seamlessly with the user's native environment, improving user experience by respecting established design patterns and accessibility settings.
System colors are particularly valuable for creating accessible interfaces that automatically adapt to user preferences, including high-contrast modes and system-level theme settings. When implementing these, ensure your web development workflow includes accessibility testing to validate the visual hierarchy.
1/* Named colors - easy to read and maintain */2.primary { color: firebrick; }3.accent { color: cornflowerblue; }4.success { color: forestgreen; }5.warning { color: goldenrod;6/* More specific shades for precise control */7.surface-light { background: aliceblue; }8.surface-dark { background: darkslategray; }9 10/* Special keywords for dynamic behavior */11.transparent-bg { background: transparent; }12.hover-overlay { background: rgba(0, 0, 0, 0.5); }13 14/* currentColor - icons match text color */15.icon { color: currentColor; }16.icon:hover { color: var(--hover-color, inherit); }17 18/* System colors - adapt to user preferences */19.native-button { background: buttonface; border: 1px solid buttonborder; }20.native-text { color: accentcolortext; }21.native-canvas { background: canvas; }22.native-link { color: linktext; }RGB and Hexadecimal Colors
Hexadecimal Notation
Hexadecimal string notation represents colors using hexadecimal digits for red, green, and blue components, optionally followed by alpha channel values. The format begins with a # character and can use either six digits (#rrggbbaa) or three digits (#rgba) for shorthand notation.
The three-digit shorthand works by doubling each digit, so #f00 becomes #ff0000 (red). This format is particularly concise for common colors and reduces file size when used extensively in stylesheets. Hex notation remains the most popular choice in production codebases due to its brevity and universal support.
RGB Functional Notation
The rgb() function accepts red, green, and blue components as numbers (0-255) or percentages, along with an optional alpha channel. Modern CSS allows space-separated syntax for better readability:
/* Traditional comma syntax - still valid */
.legacy { color: rgb(37, 99, 235); }
/* Modern space-separated syntax - recommended */
.modern { background: rgb(37 99 235); }
/* Alpha channel using slash notation */
.with-alpha { border: rgb(37 99 235 / 0.5); }
The space-separated syntax with slash notation for alpha has become the recommended approach, as it's easier to read and write, especially when combining multiple color functions or using calc() for color manipulation. This modern syntax also aligns better with emerging CSS features like relative color syntax and color-mix().
Both hex and RGB formats have their place in modern CSS. Hex is preferred for single color values where brevity matters, while RGB functional notation shines when you're performing calculations or need programmatic control over individual color components.
1/* Full hex notation - most common in production */2.primary { color: #2563eb; }3.primary-alpha { color: #2563eb80; }4.success { color: #22c55e; }5.error { color: #ef4444; }6 7/* Shorthand notation - when colors have repeated digits */8.red { color: #f00; }9.green { color: #0f0; }10.blue { color: #00f; }11.red-alpha { color: #f008; }12 13/* RGB functional notation - flexible and readable */14.rgb-comma { color: rgb(37, 99, 235); }15.rgb-space { background: rgb(37 99 235); }16.rgb-alpha { border: rgb(37 99 235 / 0.5); }17 18/* Percentage values - intuitive for design */19.rgb-percent { color: rgb(15% 39% 92%); }20.rgb-percent-alpha { background: rgb(15% 39% 92% / 0.8); }21 22/* Modern syntax with calc() */23--brand: rgb(37 99 235);24--brand-light { color: rgb(from var(--brand) r g calc(b + 20)); }25--brand-dark { color: rgb(from var(--brand) r g calc(b - 30)); }HSL Color Functions
Understanding HSL
HSL separates color into three intuitive components: hue (the color on the color wheel from 0 to 360 degrees), saturation (the intensity or purity from 0% to 100%), and lightness (how light or dark from 0% black to 100% white). This separation makes it much easier to reason about color relationships and create consistent variations.
Hue 0 is red, 120 is green, and 240 is blue. Saturation 0% produces a gray regardless of hue, while 100% produces the full color. Lightness 0% is always black and 100% is always white. This intuitive model makes HSL particularly powerful for creating accessible color systems where you need to generate tints and shades that maintain sufficient contrast.
Practical HSL Applications
HSL is particularly powerful for creating color scales and theme systems. By keeping hue constant and adjusting saturation and lightness, you can generate harmonious color variations without needing specialized tools. This approach is fundamental to modern design systems and enables rapid iteration during frontend development. When building web applications, consistent color systems improve user experience and reduce cognitive load.
/* Creating a cohesive color scale */
--brand-hue: 221;
--brand-100: hsl(var(--brand-hue) 83% 97%);
--brand-200: hsl(var(--brand-hue) 83% 94%);
--brand-300: hsl(var(--brand-hue) 83% 89%);
--brand-400: hsl(var(--brand-hue) 83% 81%);
--brand-500: hsl(var(--brand-hue) 83% 67%);
--brand-600: hsl(var(--brand-hue) 83% 53%);
--brand-700: hsl(var(--brand-hue) 83% 41%);
--brand-800: hsl(var(--brand-hue) 83% 32%);
--brand-900: hsl(var(--brand-hue) 83% 23%);
This technique allows you to define a single hue and generate an entire color palette programmatically. When brand requirements change, you only need to update one value to regenerate the entire scale, making maintenance significantly easier than manually specifying each color value.
1/* HSL basics - hue, saturation, lightness */2--red: hsl(0 100% 50%);3--green: hsl(120 100% 50%);4--blue: hsl(240 100% 50%);5 6/* Saturation variations - from gray to vibrant */7--saturated: hsl(220 100% 50%);8--less-saturated: hsl(220 50% 50%);9--desaturated: hsl(220 20% 50%);10 11/* Lightness variations - from black to white */12--lightest: hsl(220 100% 95%);13--lighter: hsl(220 100% 80%);14--normal: hsl(220 100% 50%);15--darker: hsl(220 100% 30%);16--darkest: hsl(220 100% 15%);17 18/* Complementary colors - hue + 180 */19--brand: hsl(217 91% 53%);20--brand-complement: hsl(217 91% 53% + 180deg);21 22/* Analogous colors - hue +/- 30 */23--brand-analogous-1: hsl(217 91% 53% - 30deg);24--brand-analogous-2: hsl(217 91% 53% + 30deg);25 26/* Complete color scale from one base */27--brand-base: hsl(221 83% 53%);28--brand-100: hsl(221 83% 97%);29--brand-200: hsl(221 83% 94%);30--brand-300: hsl(221 83% 89%);31--brand-400: hsl(221 83% 81%);32--brand-500: hsl(221 83% 67%);33--brand-600: hsl(221 83% 53%);34--brand-700: hsl(221 83% 41%);35--brand-800: hsl(221 83% 32%);36--brand-900: hsl(221 83% 23%);Modern Color Spaces: Lab, OKLCH, and Beyond
Why Perceptually Uniform Colors Matter
Traditional color spaces like RGB and HSL don't represent colors uniformly to human perception. Two colors with the same saturation and lightness values in HSL can appear to have vastly different perceived brightness depending on their hue. This inconsistency makes it challenging to create color systems that feel consistent across the spectrum.
For example, a blue and a yellow at 50% lightness in HSL will appear dramatically different in brightness to the human eye, even though they have the same numerical lightness value. This phenomenon makes it difficult to create accessible color systems where text needs to maintain sufficient contrast across different hues.
Perceptually uniform color spaces like OKLCH and OKLab were designed to address this limitation. In these spaces, equal changes in values correspond to equal changes in perceived color, making it much easier to create color scales that maintain consistent visual weight and accessibility. These modern color spaces are essential for professional design systems that require precise color control and are increasingly recommended in web development best practices.
OKLCH Color Space
OKLCH uses three components: Lightness (L on a scale from 0 to 1), Chroma (C for color intensity with no fixed upper limit), and Hue (H in degrees). The key advantage is that colors maintain consistent perceived brightness regardless of hue.
Unlike HSL, where the same lightness value can result in wildly different perceived brightness between colors, OKLCH ensures that the visual impact remains consistent. This makes it invaluable for creating accessible interfaces and design systems. You can use tools like the OKLCH Color Picker to experiment with colors in this space.
Lab and OKLab Color Spaces
The lab() and oklab() functions work with Lightness and two axis-based color components (a and b) instead of hue and chroma. OKLab is the modern, improved version that addresses limitations in the original Lab specification, particularly around blue and purple ranges.
These color spaces are particularly useful when you need to mix colors or perform calculations while maintaining perceptual consistency. They're also essential for the color-mix() function when you want predictable, perceptually smooth results.
1/* OKLCH basics - Lightness is 0-1 (or %), C is chroma, H is degrees */2--blue-oklch: oklch(0.54 0.08 275);3--green-oklch: oklch(0.54 0.08 145);4--red-oklch: oklch(0.54 0.08 25);5 6/* All three appear equally bright - unlike HSL! */7/* HSL would show green as much brighter than red at same lightness */8 9/* High chroma for vibrant colors */10--vibrant-purple: oklch(0.55 0.3 320);11--vibrant-orange: oklch(0.65 0.2 45);12 13/* Limiting chroma for consistent saturation */14--safe-blue: oklch(0.55 0.15 245);15--safe-red: oklch(0.55 0.15 25);16 17/* OKLab example - axis-based components */18--color-oklab: oklab(54% -0.02 -0.08);19--warm-gray: oklab(55% -0.02 0.02);20--cool-gray: oklab(55% -0.02 -0.08);21 22/* Converting from other formats - works with any input */23--from-hex: oklch(from #2563eb l c h);24--from-hsl: oklch(from hsl(217 91% 53%) l c h);25--from-named: oklch(from rebeccapurple l c h);26 27/* Perceptual color scale in OKLCH */28--brand-base-oklch: oklch(0.55 0.15 245);29--brand-light: oklch(0.85 0.08 245);30--brand-dark: oklch(0.35 0.15 245);Relative Color Syntax
Introduction to Relative Colors
Relative color syntax allows you to take an existing color and extract its components as variables that you can then modify. This opens up possibilities that previously required preprocessor functions, JavaScript, or external tools. The syntax works with any color format and any color space.
/* Extract and modify color components */
--primary: #2563eb;
--lighter: hsl(from var(--primary) h s calc(l + 20%));
--more-saturated: hsl(from var(--primary) h calc(s + 10%) l);
--complementary: hsl(from var(--primary) calc(h + 180) s l);
The magic of relative colors is that you're not limited to using the original color's format. You can extract from a hex color and output to HSL, or extract from RGB and output to OKLCH - the color space of the output determines how the components are interpreted. This flexibility enables powerful color system architectures in modern CSS development and is a key technique for teams implementing AI-powered interfaces that need sophisticated theming support.
Creating Color Variations with calc()
Combining relative color syntax with calc() gives you powerful programmatic control over colors. You can create entire color scales from a single base color, generate complementary or triadic schemes, and adjust colors for different contexts without maintaining separate color values.
Perceptual Color Scaling
When creating color scales, simply adjusting lightness often produces results that feel inconsistent. Perceptual color scaling involves adjusting hue, saturation, and lightness together to maintain visual harmony. Lighter shades typically have slightly increased saturation and shifted hue, while darker shades reduce saturation.
Surface Levels for Themes
Relative colors shine when creating surface level systems for light and dark themes. In dark themes, surfaces get progressively lighter rather than using shadows to create depth. This approach creates a more natural and accessible dark mode experience that works seamlessly with modern web application architectures.
1/* Basic relative color extraction */2--primary: #2563eb;3--lighter: hsl(from var(--primary) h s calc(l + 20%));4--more-saturated: hsl(from var(--primary) h calc(s + 10%) l);5--complementary: hsl(from var(--primary) calc(h + 180) s l);6 7/* Triadic color scheme from single base */8--base: #2563eb;9--secondary: hsl(from var(--base) calc(h + 120) s l);10--tertiary: hsl(from var(--base) calc(h - 120) s l);11 12/* Perceptual color scaling - adjusts all components */13--brand: hsl(221 83% 53%);14--brand-400: hsl(from var(--brand) calc(h - 3) calc(s + 5) 60%);15--brand-300: hsl(from var(--brand) calc(h - 6) calc(s + 10) 70%);16--brand-200: hsl(from var(--brand) calc(h - 9) calc(s + 15) 80%);17--brand-100: hsl(from var(--brand) calc(h - 12) calc(s + 20) 90%);18 19/* Cross-format conversion - hex to OKLCH */20--brand-oklch: oklch(from #2563eb l c h);21--brand-light-oklch: oklch(from #2563eb calc(l + 0.2) c h);22 23/* Surface levels with theme support */24--surface-dark: hsl(252 21% 9%);25.surface-1 { background: var(--surface-dark); }26.surface-2 { background: hsl(from var(--surface-dark) h s calc(l + 4)); }27.surface-3 { background: hsl(from var(--surface-dark) h s calc(l + 8)); }28.surface-4 { background: hsl(from var(--surface-dark) h s calc(l + 12)); }29 30/* Text colors with proper contrast */31--text-on-brand: hsl(from var(--primary) calc(h + 180) calc(s - 20%) 98%);Color Mixing with color-mix()
Basic Color Mixing
The color-mix() function combines two colors in a specified color space, with an optional ratio to control the balance. By default, it mixes 50% of each color. This function enables creating intermediate colors without preprocessor functions or JavaScript.
/* Default 50/50 mix */
--purple: color-mix(in srgb, red, blue);
/* Controlling the ratio */
--red-90-blue: color-mix(in oklab, red 90%, blue);
--soft-purple: color-mix(in oklab, red, blue 30%);
Color Space Considerations
Each color space produces different mixing results due to how it represents color mathematically. The oklab space typically provides the most natural-looking mixtures, while srgb can produce more vibrant but less smooth transitions. The CSS Working Group has resolved to make oklab the default color space for color-mix().
Creating Transparency and Gradients
Color mixing can create semi-transparent colors by specifying percentages that total less than 100%, or by mixing with transparent. This is useful for creating layered effects without managing separate alpha values. When implementing these techniques in production web applications, you can create sophisticated visual effects while maintaining accessible contrast ratios.
/* Creating transparency effects */
--semi-transparent: color-mix(in oklab, red 60%, blue 20%);
--opacity-30: color-mix(in oklch, red 30%, transparent);
/* Banded gradient effect */
.gradient-band {
background: linear-gradient(
to right,
color-mix(in oklch, blue, red 0%),
color-mix(in oklch, blue, red 25%),
color-mix(in oklch, blue, red 50%),
color-mix(in oklch, blue, red 75%),
color-mix(in oklch, blue, red 100%)
);
}
1/* Basic mixing - 50/50 default */2--purple: color-mix(in srgb, red, blue);3--purple-oklab: color-mix(in oklab, red, blue);4 5/* Controlling the ratio - color percentage */6--red-90-blue: color-mix(in oklab, red 90%, blue);7--red-75-blue: color-mix(in oklab, red 75%, blue);8--red-60-blue: color-mix(in oklab, red 60%, blue);9--red-50-blue: color-mix(in oklab, red 50%, blue);10--soft-purple: color-mix(in oklab, red, blue 30%);11 12/* Different color spaces produce different results */13--mix-srgb: color-mix(in srgb, red, blue);14--mix-oklab: color-mix(in oklab, red, blue);15--mix-oklch: color-mix(in oklch, red, blue);16 17/* OKLCH preserves color vibrancy better during mixing */18--vibrant-mix: color-mix(in oklch, #ff6b35, #2ec4b6);19 20/* Creating transparency with percentages */21--semi-transparent: color-mix(in oklab, red 60%, blue 20%);22--mostly-blue: color-mix(in oklab, red 10%, blue 70%);23--opacity-30: color-mix(in oklch, red 30%, transparent);24--opacity-50: color-mix(in oklch, red 50%, transparent);25 26/* Banded gradient without intermediate stops */27.gradient-band {28 background: linear-gradient(29 to right,30 color-mix(in oklch, blue, red 0%),31 color-mix(in oklch, blue, red 25%),32 color-mix(in oklch, blue, red 50%),33 color-mix(in oklch, blue, red 75%),34 color-mix(in oklch, blue, red 100%)35 );36}37 38/* Theme-aware surface colors */39--surface-mix: color-mix(in oklab, var(--brand) canvas 20%);40--surface-hover: color-mix(in oklab, var(--brand) canvas 10%);Light-Dark() for Automatic Theming
Automatic Theme Switching
The light-dark() function enables elegant theme switching without media query hacks or JavaScript. It automatically selects between two colors based on the user's system preference (light or dark mode). This approach works seamlessly with the prefers-color-scheme media feature and respects user system preferences automatically.
/* Basic light-dark usage */
--text-primary: light-dark(#1a1a1a, #f5f5f5);
--text-secondary: light-dark(#666666, #a0a0a0);
--background: light-dark(#ffffff, #121212);
--border: light-dark(#e0e0e0, #333333);
body {
color: var(--text-primary);
background: var(--background);
}
Combining with Relative Colors
Light-dark() becomes even more powerful when combined with relative color syntax, allowing you to create theme-aware color variations that adjust appropriately for each mode. This is particularly valuable for design systems that need to maintain consistent visual relationships between colors across themes. Implementing automatic theming also contributes to better SEO performance by improving user engagement metrics.
/* Brand colors that adapt to theme */
--brand: #2563eb;
--brand-dark: light-dark(
var(--brand),
hsl(from var(--brand) h s calc(l - 10%))
);
This combination enables sophisticated theming systems where a single color definition automatically generates appropriate variants for both light and dark modes, reducing maintenance overhead and ensuring visual consistency across themes.
1/* Basic light-dark usage - automatic theme switching */2--text-primary: light-dark(#1a1a1a, #f5f5f5);3--text-secondary: light-dark(#666666, #a0a0a0);4--text-muted: light-dark(#9ca3af, #6b7280);5--background: light-dark(#ffffff, #121212);6--background-secondary: light-dark(#f8fafc, #1e1e2e);7--surface: light-dark(#ffffff, #1e1e2e);8--border: light-dark(#e0e0e0, #333333);9--border-subtle: light-dark(#e5e7eb, #2d2d3a);10 11body {12 color: var(--text-primary);13 background: var(--background);14}15 16/* Typography with automatic contrast */17.heading { color: var(--text-primary); }18.body-text { color: var(--text-secondary); }19.caption { color: var(--text-muted); }20 21/* Surface cards with subtle theming */22.card {23 background: var(--surface);24 border: 1px solid var(--border);25}26 27/* Combining with relative colors */28--brand: #2563eb;29--brand-light: light-dark(30 var(--brand),31 hsl(from var(--brand) h calc(s + 5%) calc(l + 10%))32);33--brand-dark: light-dark(34 var(--brand),35 hsl(from var(--brand) h s calc(l - 10%))36);37 38--surface-light: hsl(240 67% 97%);39--surface-dark: hsl(252 21% 9%);40 41.surface-1 {42 background: light-dark(43 var(--surface-light),44 var(--surface-dark)45 );46}47 48.surface-2 {49 background: light-dark(50 var(--surface-light),51 hsl(from var(--surface-dark) h s calc(l + 4))52 );53}54 55.surface-3 {56 background: light-dark(57 var(--surface-light),58 hsl(from var(--surface-dark) h s calc(l + 8))59 );60}61 62/* Interactive states with theme awareness */63.button-primary {64 background: var(--brand);65 color: white;66}67 68.button-primary:hover {69 background: var(--brand-dark);70}Summary
Modern CSS color has transformed from a simple specification system into a sophisticated toolkit for color manipulation. From basic named colors to perceptual color spaces like OKLCH, from static hex values to dynamic relative color syntax with calc(), and from hardcoded theme values to automatic light-dark() switching, developers now have unprecedented control over how colors are defined, mixed, and adapted.
The combination of relative color syntax, color-mix(), and perceptual color spaces enables design system architectures that would have required preprocessors, JavaScript, or external tools just a few years ago. As browser support continues to improve and new features arrive, the possibilities will only expand further.
Start with small experiments - converting a color scale to relative colors, implementing light-dark() for a single component - and build from there toward comprehensive color systems that are maintainable, accessible, and visually consistent. The key is understanding not just the syntax, but the underlying color spaces and perceptual models that make modern CSS color so powerful.
For teams building sophisticated web applications, mastering these color techniques is essential for creating interfaces that adapt to user preferences, maintain accessibility across all color combinations, and scale gracefully as design requirements evolve. Whether you're building custom web solutions or implementing AI-powered platforms, these CSS color techniques will improve your development workflow and end-user experience.
Frequently Asked Questions
What is the difference between HSL and OKLCH?
HSL is intuitive but not perceptually uniform - colors at the same lightness can appear to have different brightness depending on hue. OKLCH is perceptually uniform, meaning equal changes in values produce equal perceived changes. This makes OKLCH better for creating consistent color scales, while HSL remains useful for quick prototyping and simpler color manipulations.
Do I need to specify a color space for color-mix()?
Currently yes, but the CSS Working Group has resolved to make oklab the default. Once browsers implement this change, the color space parameter will become optional. Until then, always specify the color space explicitly for consistent behavior.
What browsers support relative color syntax?
Relative color syntax is supported in all modern browsers including Chrome 119+, Firefox 128+, Safari 16.4+, and Edge 119+. For older browser support, consider feature detection with @supports or provide fallback custom properties.
How does light-dark() work with user preferences?
light-dark() automatically responds to the user's system preference (light or dark mode) through the prefers-color-scheme media feature. No JavaScript or additional CSS required - it seamlessly adapts to whatever theme the user has configured in their operating system.
Can I use relative color syntax with any color format?
Yes! You can extract from any color format (hex, rgb, hsl, named colors) and output to any other format. The color space of the output determines how the components are interpreted. This flexibility enables powerful color system architectures.
How do I migrate an existing project to modern CSS colors?
Start by converting hardcoded colors to CSS custom properties. Then add perceptual color spaces for new features. Implement relative colors for generating variations. Finally, add light-dark() for automatic theme support. This gradual approach minimizes risk while improving maintainability.
Are OKLCH colors supported in all browsers?
OKLCH has good support in modern browsers including Chrome 111+, Firefox 113+, and Safari 16.4+. For projects requiring broader compatibility, use feature detection with @supports or provide hex/rgb fallbacks for older browsers.
Sources
- MDN Web Docs: CSS color values - Comprehensive official documentation covering all color value types from keywords to modern color spaces
- Piccalilli: A pragmatic guide to modern CSS colours - part two - Deep technical guide on relative color syntax, color-mix(), perceptual color scaling, and OKLCH vs HSL
- OKLCH Color Picker - Interactive color picker tool for OKLCH color space with chroma limits visualization
- Zeroheight: Leveraging modern CSS color features in your design system - Practical design system approach to modern CSS colors including variables, color spaces, and mixing
- CSS Working Group: color-mix() specification - Official specification details for the color-mix() function