Sass Color Functions — Complete Guide
In this tutorial, you will learn about Sass Color Functions. We cover key concepts, practical examples, and best practices to help you master this topic.
Sass color functions from sass:color module manipulate hue, saturation, lightness, and alpha for programmatic palette generation and consistent theming.
What You'll Learn
- The sass:color module
- HSL manipulation functions
- Color mixing and blending
- Alpha and opacity functions
- Color channel extraction
- Palette generation from a base color
- Accessibility contrast checking
Why It Matters
- Manual color values are hard to maintain
- Programmatic palettes ensure consistency
- Color functions automate theme generation
- Contrast checking improves accessibility
Real-World Use
- A design system generates hover states with darken
- A theme engine creates light/dark variants
- A component library computes accessible text colors
- A data visualization tool generates distinct chart colors
flowchart LR A[sass:color] --> B[Adjust] A --> C[Mix] A --> D[Extract] B --> E[darken, lighten] B --> F[saturate, desaturate] C --> G[mix, blend] D --> H[hue, saturation, lightness]
Color Manipulation
Code Example: HSL Adjustments
@use 'sass:color';
$primary: #0066CC;
// Lightness adjustments
.element-1 {
background: $primary; // #0066CC
background: color.adjust($primary, $lightness: 10%); // Darken
}
// Convenience functions (global, still work but prefer module)
.element-2 {
background: darken($primary, 10%); // Deprecated but common
color: lighten($primary, 60%); // Lightened
}
// Using sass:color module
$dark-primary: color.adjust($primary, $lightness: -15%);
$light-primary: color.adjust($primary, $lightness: 30%);
$desaturated: color.adjust($primary, $saturation: -30%);
$shifted: color.adjust($primary, $hue: 30deg);
// Scale (percentage of remaining space)
$scaled: color.scale($primary, $lightness: 50%); // Lighten by 50% of remaining
// Color palette from base
$brand: #0066CC;
$palette: (
'50': color.scale($brand, $lightness: 80%),
'100': color.scale($brand, $lightness: 60%),
'200': color.scale($brand, $lightness: 40%),
'300': color.scale($brand, $lightness: 20%),
'400': color.scale($brand, $lightness: 10%),
'500': $brand,
'600': color.scale($brand, $lightness: -10%),
'700': color.scale($brand, $lightness: -20%),
'800': color.scale($brand, $lightness: -40%),
'900': color.scale($brand, $lightness: -60%)
);
@each $name, $color in $palette {
.bg-primary-#{$name} { background: $color; }
.text-primary-#{$name} { color: $color; }
}
Expected output: color.adjust() modifies HSL channels by fixed amounts. color.scale() adjusts by a percentage of the remaining range, creating more natural variations. The palette generation creates 10 shades from a single base color.
Code Example: Color Mixing
@use 'sass:color';
// Mix two colors
.element {
background: color.mix(#0066CC, #ff6600, 50%);
// 50% blue + 50% orange = blended brownish color
}
// Mix with white (tint) and black (shade)
@function tint($color, $percentage) {
@return color.mix($color, white, $percentage);
}
@function shade($color, $percentage) {
@return color.mix($color, black, $percentage);
}
// Usage
$primary: #0066CC;
.btn-primary {
background: $primary;
&:hover {
background: shade($primary, 20%); // Darker
}
&:active {
background: shade($primary, 40%); // Even darker
}
}
.btn-primary-light {
background: tint($primary, 30%); // Lighter variant
}
// Complementary and analogous colors
$complement: color.complement($primary); // Opposite on color wheel
// Grayscale
$gray: color.grayscale($primary); // Remove all saturation
// Invert
$inverted: color.invert($primary); // Inverted color
Expected output: color.mix() blends two colors at a specified weight. The tint() and shade() utility functions create lighter and darker variants. color.complement() and color.invert() generate related colors.
Code Example: Alpha and Opacity
@use 'sass:color';
// Set alpha
.element {
background: color.adjust(#0066CC, $alpha: -0.5);
// Same as rgba(0, 102, 204, 0.5)
}
// Alpha with opacity function
.overlay {
background: rgba(#0066CC, 0.3);
}
// Fade helpers
$primary: #0066CC;
@function fade($color, $amount) {
@return color.adjust($color, $alpha: -$amount);
}
@function opacify($color, $amount) {
@return color.adjust($color, $alpha: $amount);
}
// Usage
.overlay {
background: fade($primary, 0.5); // 50% transparent
}
.modal-backdrop {
background: fade(#000, 0.6); // 60% transparent black
}
// Alpha channel extraction
.element {
$alpha: color.alpha(rgba(#0066CC, 0.5)); // 0.5
opacity: $alpha;
}
// Red, Green, Blue channels
$color: #4CAF50;
$red: color.red($color); // 76
$green: color.green($color); // 175
$blue: color.blue($color); // 80
// HSL channels
$hue: color.hue($color); // ~122 degrees
$sat: color.saturation($color); // ~50%
$light: color.lightness($color); // ~50%
Expected output: Alpha functions create transparent variants of any color. Channel extraction functions (red, green, blue, hue, saturation, lightness) decompose colors into their components.
Code Example: Accessibility and Contrast
@use 'sass:color';
// Contrast ratio calculation
@function contrast-ratio($background, $text) {
$l1: color.luminance($background);
$l2: color.luminance($text);
@if $l1 > $l2 {
@return ($l1 + 0.05) / ($l2 + 0.05);
} @else {
@return ($l2 + 0.05) / ($l1 + 0.05);
}
}
// Background luminance
@function luminance($color) {
$red: color.red($color) / 255;
$green: color.green($color) / 255;
$blue: color.blue($color) / 255;
$red: if($red <= 0.03928, $red / 12.92, math.pow(($red + 0.055) / 1.055, 2.4));
$green: if($green <= 0.03928, $green / 12.92, math.pow(($green + 0.055) / 1.055, 2.4));
$blue: if($blue <= 0.03928, $blue / 12.92, math.pow(($blue + 0.055) / 1.055, 2.4));
@return 0.2126 * $red + 0.7152 * $green + 0.0722 * $blue;
}
// Choose black or white text for readability
@function readable-text($bg) {
@if color.lightness($bg) > 50% {
@return #333; // Dark text
} @else {
@return #fff; // Light text
}
}
// Usage
$primary: #0066CC;
$text-on-primary: readable-text($primary); // #fff
.button {
background: $primary;
color: $text-on-primary;
&:hover {
background: color.adjust($primary, $lightness: -10%);
}
}
// Ensure minimum contrast
@function ensure-contrast($bg, $text, $min-ratio: 4.5) {
$ratio: contrast-ratio($bg, $text);
@if $ratio < $min-ratio {
@warn "Contrast ratio #{$ratio} is below minimum #{$min-ratio} for #{$text} on #{$bg}";
}
@return $ratio;
}
Expected output: contrast-ratio() calculates WCAG contrast ratios. readable-text() chooses appropriate light or dark text for any background. ensure-contrast() warns about accessibility issues during compilation.
Common Mistakes
- Using global color functions without sass:color module — darken(), lighten(), saturate() still work but are deprecated. Use color.adjust() or color.scale().
- Confusing adjust and scale — adjust() adds/subtracts a fixed amount. scale() adjusts by a percentage of remaining space. scale usually produces more natural results.
- Not accounting for color blindness — Generated palettes may not distinguish for all users. Test with contrast checkers.
- Over-darkening or over-lightening — Adjusting lightness beyond 100% or below 0% fails. Use scale() which respects the range.
- Forgetting that mix() uses weight, not percentage — color.mix($a, $b, 25%) means 25% $a and 75% $b.
- Inconsistent alpha values — Mixing opaque and transparent colors can produce unexpected results. Use rgba() or alpha functions consistently.
- Not testing generated colors visually — Programmatic colors may not look as expected. Always preview generated palettes.
Practice Questions
- What is the difference between color.adjust() and color.scale()? adjust() adds/subtracts a fixed amount. scale() adjusts by a percentage of the remaining range.
- How do you mix two colors at a 50/50 ratio? color.mix($color1, $color2, 50%)
- What function extracts the lightness of a color? color.lightness($color) returns the HSL lightness value.
- How do you create a semi-transparent variant of a color? color.adjust($color, $alpha: -0.5) or use rgba($color, 0.5).
FAQ
Mini Project
Build a complete color system from a single primary color ($brand: #0066CC). Generate: a 10-step palette (50-900) using color.scale(), complementary palette using color.complement(), analogous palette (3 colors shifted by 30 degrees), a tint/shade function using color.mix(), an alpha utility for transparency, and the readable-text() function for accessible text. Create utility classes (text-, bg-, border-) for all palette colors. Build a sample UI (navbar, buttons, cards, alerts) that demonstrates all generated colors. Test contrast ratios for all text-on-background combinations.
What's Next
Continue with Lesson 12: Sass Lists to learn list manipulation in Sass.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro