color.scale() belongs to the built-in sass:color module. It fluidly scales one or more color channels toward their maximum or minimum by a percentage of the remaining room. This page covers how percentages work, how scale differs from adjust and change, optional $space (Dart Sass 1.79+), and five compiled examples.
01
Concept
Fluid scaling
02
Module
@use "sass:color"
03
Range
-100% … 100%
04
Vs
adjust & change
05
Space
Optional (1.79+)
06
Practice
5 examples
Concept
What Is color.scale()?
Scale means “slide this dial a percentage of the way toward its end stop.” Official docs: each keyword argument between -100% and 100% moves a property from its current position toward the maximum (positive) or minimum (negative). So $lightness: 50% makes colors 50% closer to maximum lightness without jumping all the way to white.
color.scale(#6b717f, $red: 15%) → #81717f (docs also show rgb(129.2, 113, 127))
Think of a volume slider: 50% is not “add 50,” it is “go halfway from here to the top.” Dark colors still have lots of room to lighten; already-light colors move less before they hit white.
Foundation
📝 Syntax
Load the color module, then pass a color plus keyword channel percentages:
Scale RGB channels toward their max/min (-100%–100%).
$saturation / $lightness
Percentage
Scale HSL saturation or lightness toward their bounds.
$whiteness / $blackness
Percentage
Scale HWB channels (Dart Sass 1.28+).
$chroma / $x / $y / $z
Percentage
Modern space channels (Dart Sass 1.79+).
$alpha
Percentage
Scale opacity toward fully opaque or fully transparent.
$space
Color space name
Scale channels in another space (Dart Sass 1.79+), e.g. oklch. Result still returns in $color’s space.
Return value
Type
Meaning
Color
A new color in the same space as $color, with the requested fluid scales applied.
Modules
📦 Loading sass:color
Prefer the module API. Official docs also document the global name scale-color() for older stylesheets.
styles.scss
// Recommended — namespaced
@use "sass:color";
$c: color.scale(#6b717f, $red: 15%);
// Optional — bring members into the current namespace
@use "sass:color" as *;
$c: scale(#6b717f, $red: 15%);
// Optional — custom namespace
@use "sass:color" as c;
$c: c.scale(#6b717f, $red: 15%);
// Legacy global name
$c: scale-color(#6b717f, $red: 15%);
⚠️
Put @use first
Keep @use "sass:color"; near the top of the file. Built-in modules need Dart Sass (about 1.23+). Passing $space, $chroma, or xyz channels needs 1.79+.
Rules
⚖️ How Fluid Scaling Works
Official docs: each percentage says how far to move from the current value toward the channel’s maximum (positive) or minimum (negative).
Argument
Meaning
$lightness: 100%
Go all the way to maximum lightness
$lightness: 50%
Move halfway from current lightness toward maximum
$lightness: 0%
No change
$lightness: -50%
Move halfway toward minimum lightness
⚠️
Heads up from the docs
For legacy colors, do not mix RGB channels with HSL channels in one call, or either of those with HWB channels—Sass errors. Even so, official guidance: pass $space explicitly once you are on Dart Sass 1.79+.
Compare
📋 scale vs adjust vs change
Official docs point to these three siblings for different jobs.
Helper
What it does
Mental model
color.scale()
Scale toward a bound by a %
“Move 20% of the way lighter”
color.adjust()
Add/subtract fixed amounts
“Plus 10% lightness”
color.change()
Set channels to exact values
“Make lightness exactly 70%”
Support
🛠 Compatibility
This is about Sass compilers, not browsers. Compiled CSS receives a finished color—no color.scale() call remains.
Feature
Dart Sass
Notes
@use "sass:color" / color.scale
1.23+
Preferred module API
$whiteness / $blackness
1.28+
HWB channel scaling
$space, $chroma, $x/$y/$z
1.79+
Modern color-space scaling
Global scale-color()
Long-standing
Prefer module form in new SCSS
LibSass / Ruby Sass
No modern module API
May expose scale-color(); prefer Dart Sass
Cheat Sheet
⚡ Quick Reference
Goal
Code
Import color
@use "sass:color";
Scale red toward max
color.scale(#6b717f, $red: 15%)
Lighten fluidly
color.scale($c, $lightness: 20%)
Darken fluidly
color.scale($c, $lightness: -25%)
Fade alpha
color.scale($c, $alpha: -40%)
Scale in oklch (1.79+)
color.scale($c, $lightness: -10%, $space: oklch)
Legacy global
scale-color(#6b717f, $red: 15%)
Hands-On
Examples Gallery
Examples 1–3 and 5 compile on everyday Dart Sass. Example 4 shows official $space / chroma results for Dart Sass 1.79+. Open View Compiled CSS to inspect the output.
📚 Getting Started
Scale a single channel, then combine lightness and alpha.
Example 1 — Scale the Red Channel
Move red 15% of the way toward its maximum (classic docs sample).
Lightness moves 10% toward minimum; alpha moves 50% toward fully transparent. The HWB example pushes whiteness up and blackness down for a washed gray.
📈 Practical Patterns
Sibling helpers, modern $space, and brand token ladders.
Example 3 — Scale vs Adjust vs Change
Same starting color, three different “make it lighter” tools.
scale moves 20% of the remaining room toward max lightness. adjust adds a fixed 20% lightness. change jumps to absolute 70% lightness. Three different midtones from one seed.
Example 4 — Scale in Another Space (Dart Sass 1.79+)
Scaling lightness in oklch uses perceptual lightness, then returns a color in the original space of $color. Chroma 50% moves halfway toward max chroma; alpha -40% fades toward transparent.
Example 5 — Brand Token Ladder + Global Alias
Build hover-ready steps from one brand hex; module and global names match.
One brand seed becomes text, border, muted outline, and a soft translucent twin. Module color.scale and global scale-color emit the same hex.
Applications
🚀 Real-World Use Cases
Hover / active states — fluidly lighten or darken without hardcoding new hexes.
Soft borders — scale saturation or lightness toward a quieter twin.
Overlay fades — scale alpha toward transparent for chips and sheets.
Token ladders — generate related steps that stay proportional on light and dark seeds.
Perceptual tweaks — use $space: oklch on Dart Sass 1.79+.
Teaching color math — contrast scale vs adjust vs change side by side.
🧠 How Compilation Works
1
Write SCSS
Call color.scale($color, ...) after @use.
Source
2
Pick a space
Use $space (1.79+) or scale in $color’s own space.
Space
3
Fluid move
Slide each channel a % of the remaining room toward min/max.
Scale
4
✓
Plain CSS color ships
Browsers receive hex/rgb/oklch—not a Sass call.
Watch Out
⚠️ Common Pitfalls
Treating % like adjust — $lightness: 20% is not the same as adjust(..., $lightness: 20%).
Mixing RGB + HSL keywords — on legacy colors Sass errors if you combine those families (or with HWB) in one call.
Using $space on older Dart Sass — needs 1.79+; bare channel scales still work earlier.
Expecting full white from 50% — 50% only moves halfway toward maximum lightness.
Forgetting units — scale arguments are percentages such as 15%, not bare 15.
Pro Tips
💡 Best Practices
✅ Do
Use @use "sass:color" and color.scale() in new SCSS
Prefer scale when relative, proportional shifts look more natural
Pass $space explicitly on Dart Sass 1.79+
Keep one channel family per call on legacy colors
Check contrast after lightening interactive text
❌ Don’t
Expect the browser to re-run color.scale
Confuse scale percentages with adjust amounts
Mix RGB and HSL keywords in one legacy call
Rely on LibSass for sass:color
Skip accessibility checks on scaled UI colors
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about color.scale()
Fluid % moves toward min/max—not the same as adjust.
5
Core concepts
📝01
Call
scale($color, …)
API
📦02
Module
sass:color
@use
🎨03
Does
fluid channel scale
Scale
⚡04
Range
-100% … 100%
Bounds
✓05
Unlike
adjust / change
Siblings
❓ Frequently Asked Questions
color.scale($color, ...) fluidly scales one or more channel properties toward their maximum or minimum by a percentage. Example: color.scale(#6b717f, $red: 15%) moves red 15% of the way toward its maximum.
scale moves a percentage of the remaining room toward a bound. adjust adds or subtracts fixed amounts. change sets channels to absolute new values.
Each keyword argument must be a number between -100% and 100% (inclusive). Positive values move toward the channel maximum; negative values move toward the minimum.
Add @use "sass:color"; then call color.scale($brand, $lightness: 20%) or other channel keywords. Prefer the module form. The global alias is scale-color().
On Dart Sass 1.79+, $space lets you scale channels in another color space (for example oklch) while still returning a color in $color’s original space.
The module form needs Dart Sass with @use (about 1.23+). $whiteness/$blackness need 1.28+. $space, $chroma, and xyz channels need 1.79+. LibSass/Ruby Sass may expose scale-color() but lack the modern module API.
Did you know?
Official Sass docs emphasize that $lightness: 50% never forces every color to the same mid gray—it only moves each color halfway from its own lightness toward maximum. That is why scale often looks more natural than a fixed adjust on mixed light and dark brand tokens.
color.scale() is the clearest way to ask Sass for proportional channel moves. Use percentages toward min/max, keep adjust for fixed amounts, change for absolute values, and pass $space on Dart Sass 1.79+ when perceptual spaces matter.