Technical
CSS Color Functions for Developers
personWritten by Sofia Thornwood
•calendar_todayJanuary 28, 2026
•schedule7 min read
CSS color handling has evolved far beyond simple HEX codes. Modern CSS offers powerful color functions that give developers precise control over hue, saturation, lightness, and even color mixing directly in stylesheets. These functions make it easier to build consistent design systems, create accessible color palettes, and implement features like dark mode. This guide covers the essential CSS color functions every frontend developer should know, from the familiar rgb() and hsl() to newer additions like oklch() and color-mix().
rgb() and rgba(): the foundation
The rgb() function has been a CSS staple for decades, defining colors through red, green, and blue channels.
Modern syntax (CSS Color Level 4):
• rgb(255 128 0) — space-separated values, no commas needed
• rgb(255 128 0 / 0.5) — 50% opacity using slash notation
• rgb(100% 50% 0%) — percentage values supported
• Legacy: rgba(255, 128, 0, 0.5) still works but is no longer required
When to use rgb():
• When working with design tools that output RGB values
• When performing calculations with individual color channels
• When converting from programmatic color values (canvas, WebGL)
Limitations:
• Not intuitive for humans — hard to predict a color from its RGB values
• Adjusting brightness or saturation requires changing multiple channels
• Creating color palettes by hand is tedious
Pro tip: Use a color converter tool to quickly translate between RGB, HEX, and HSL when you need to switch formats for different contexts.
hsl() and hsla(): human-friendly colors
The hsl() function uses hue, saturation, and lightness — a model that matches how humans think about color.
Syntax:
• hsl(220 80% 50%) — hue in degrees, saturation and lightness in %
• hsl(220 80% 50% / 0.7) — with 70% opacity
• hsl(220deg 80% 50%) — explicit degree unit
The color wheel:
• 0°/360° = red
• 60° = yellow
• 120° = green
• 180° = cyan
• 240° = blue
• 300° = magenta
Why developers love hsl():
• Easy to create lighter/darker variants by changing lightness
• Create color palettes by rotating hue while keeping saturation and lightness
• Accessible contrast pairs: same hue, different lightness values
• Design tokens become more readable: --primary: hsl(220 80% 50%)
Practical example — button states:
• Default: hsl(220 80% 50%)
• Hover: hsl(220 80% 45%)
• Active: hsl(220 80% 40%)
• Disabled: hsl(220 20% 70%)
Changing one number creates consistent, predictable variations.
oklch(): the future of CSS color
The oklch() function represents colors in a perceptually uniform color space, solving problems that hsl() can't.
Syntax:
• oklch(70% 0.15 220) — lightness, chroma, hue
• oklch(70% 0.15 220 / 0.8) — with opacity
Why oklch() matters:
• Perceptually uniform: 50% lightness actually looks like mid-brightness across all hues
• In hsl(), "50% lightness" looks different for blue vs yellow
• Consistent perceived brightness across your entire color palette
• Wider gamut support for modern displays (P3, Rec. 2020)
Comparing hsl() vs oklch():
• hsl(60 100% 50%) and hsl(240 100% 50%) — both "50% lightness" but yellow looks much brighter than blue
• oklch(70% 0.15 90) and oklch(70% 0.15 260) — both look equally bright, as intended
Practical uses:
• Building accessible color palettes with guaranteed contrast ratios
• Creating smooth color transitions and gradients
• Dark mode palettes where lightness values map consistently
• Design systems that need precise perceptual consistency
Browser support:
• Supported in all modern browsers (Chrome 111+, Firefox 113+, Safari 15.4+)
• Use @supports for progressive enhancement if needed
color-mix(): blending colors in CSS
The color-mix() function lets you blend two colors directly in CSS, eliminating the need for preprocessor mix functions.
Syntax:
• color-mix(in srgb, blue, white) — 50/50 mix
• color-mix(in srgb, blue 70%, white) — 70% blue, 30% white
• color-mix(in oklch, var(--primary), black 20%) — darken by 20%
Color spaces for mixing:
• in srgb: standard color space, most predictable for web
• in oklch: perceptually uniform mixing, best results
• in hsl: mixes along the hue wheel
• in lab: another perceptual option
Practical applications:
• Create hover states: color-mix(in oklch, var(--btn-bg), black 15%)
• Generate tints: color-mix(in oklch, var(--primary), white 40%)
• Transparent overlays: color-mix(in srgb, var(--overlay) 60%, transparent)
• Theme variations from a single base color
Replacing Sass/Less mix functions:
• Sass: mix($blue, $white, 70%) → CSS: color-mix(in srgb, blue 70%, white)
• No build step required
• Works with CSS custom properties (Sass mix can't)
• Reduces preprocessor dependency
CSS custom properties and color functions
Combining CSS custom properties with color functions creates powerful, maintainable theme systems.
Pattern 1 — HSL components:
• --primary-h: 220;
• --primary-s: 80%;
• --primary-l: 50%;
• Usage: hsl(var(--primary-h) var(--primary-s) var(--primary-l))
• Advantage: modify individual components for variants
Pattern 2 — Base color with color-mix():
• --primary: oklch(55% 0.2 250);
• --primary-light: color-mix(in oklch, var(--primary), white 30%);
• --primary-dark: color-mix(in oklch, var(--primary), black 20%);
• Advantage: entire palette derived from one value
Dark mode with color functions:
• :root { --bg: oklch(98% 0 0); --text: oklch(15% 0 0); }
• .dark { --bg: oklch(15% 0 0); --text: oklch(90% 0 0); }
• All component colors automatically adapt through custom properties
Accessibility benefits:
• Calculate contrast ratios using lightness values in oklch()
• Ensure WCAG AA (4.5:1) or AAA (7:1) by controlling lightness difference
• Build entire palettes that guarantee accessibility
• Test your color combinations with our color converter tool
Practical migration guide
Moving from HEX codes to modern color functions is straightforward.
Step 1 — Audit your colors:
• List all HEX values in your stylesheets
• Group related colors (primary, secondary, neutral, status)
• Identify patterns (lighter/darker variants of the same hue)
Step 2 — Convert to hsl() or oklch():
• Use a color converter to translate HEX to HSL or OKLCH
• Define base colors as CSS custom properties
• Replace hard-coded variants with color-mix() derivations
Step 3 — Build your system:
• One base hue per brand color
• Derive all variants using lightness and saturation changes
• Use color-mix() for interactive states (hover, active, disabled)
• Document your color tokens
Before:
• 12 HEX codes for a button (colors, hover, focus, disabled across themes)
• Each manually picked, no consistent relationship
After:
• 1 base color + 3 color-mix() rules
• Consistent, predictable, maintainable
• Theme changes require updating one variable
Tools that help:
• Color converter for format translation
• Browser DevTools color picker now shows oklch()
• Figma and design tools increasingly support oklch
Conclusion
Modern CSS color functions eliminate much of the pain in managing colors across a project. Start with hsl() if you're still using HEX everywhere, graduate to oklch() for perceptually uniform palettes, and use color-mix() to derive variants without duplication. Use the SD6 Tools color converter to translate between formats as you migrate your codebase, and explore the differences between HEX, RGB, HSL, and CMYK in practice.
Frequently Asked Questions
Not necessarily. HEX codes are still valid CSS and useful for quick one-off colors. However, for design systems, theme management, and any project with color variants, hsl() or oklch() with CSS custom properties is significantly more maintainable. Consider migrating gradually, starting with your most-used colors.