color.change() belongs to the built-in sass:color module. It sets one or more channels to the exact values you pass—make red exactly 100, lightness exactly 30%, opacity exactly 0.4—at compile time. This page covers channel keywords, mixing rules, the no-clamping rule, how it differs from adjust and scale, and five compiled examples.
01
Concept
Exact channel values
02
Module
@use "sass:color"
03
Channels
RGB · HSL · alpha
04
Vs
adjust & scale
05
Rule
Never clamps
06
Practice
5 examples
Concept
What Is color.change()?
Change means “take this color and replace one or more channels with new absolute values.” You are not adding 15 to red—you are setting red to 100. Official docs describe it as using each keyword argument in place of the corresponding channel.
Think of dials you set to a target number: $red: 100 snaps red to 100, $lightness: 30% snaps lightness to 30%, $alpha: 0.4 snaps opacity to 40%. The original color is never mutated—Sass returns a new color.
Foundation
📝 Syntax
Load the color module, then call the function with keyword channel arguments:
Set RGB channels to these exact values (typically unitless 0–255 for legacy RGB).
$hue
Angle
Set hue to this angle (for example 200deg).
$saturation / $lightness
Percentage
Set HSL saturation or lightness to this exact %.
$whiteness / $blackness
Percentage
Set HWB channels (Dart Sass 1.28+).
$alpha
Number
Set opacity to this exact value (for example 0.4).
$space
Color space name
Change channels in another space (Dart Sass 1.79+), e.g. hsl, oklch.
Return value
Type
Meaning
Color
A new color in the same space as $color, with the requested channels replaced. Official docs: channels are never clamped for color.change().
Modules
📦 Loading sass:color
Prefer the module API. Official docs also document a global name, change-color(), for older stylesheets.
styles.scss
// Recommended — namespaced
@use "sass:color";
$c: color.change(#6b717f, $red: 100);
// Optional — bring members into the current namespace
@use "sass:color" as *;
$c: change(#6b717f, $red: 100);
// Optional — custom namespace
@use "sass:color" as c;
$c: c.change(#6b717f, $red: 100);
// Legacy global name
$c: change-color(#6b717f, $red: 100);
⚠️
Put @use first
Keep @use "sass:color"; near the top of the file. Built-in modules need Dart Sass (about 1.23+).
Rules
🎨 Channel Mixing Rules
The same legacy rules as color.adjust() apply: do not mix RGB keywords with HSL keywords in the same call, or mix those with HWB keywords. Pick one family per call.
Pass $space explicitly (for example $space: hsl or oklch) when you want to change channels in a chosen color space. Older Dart Sass still supports setting HSL channels on hex/RGB colors without $space.
Important
⚠️ No Clamping on change
Official docs call this out clearly: channels are never clamped for color.change(). That differs from color.adjust(), where several channels clamp if they leave their native range.
Helper
Clamping?
When to prefer it
color.change()
Never
You need an exact channel value from a design token
color.adjust()
Some channels may clamp
You want a relative “nudge” from the current color
💡
Practical takeaway
Use change when the design says “background lightness is 92%” or “overlay alpha is 0.4.” Use adjust when the design says “10% lighter than the brand color.”
Support
🛠 Compatibility
This is about Sass compilers, not browsers. Compiled CSS receives a finished color—no color.change() call remains.
Feature
Dart Sass
Notes
@use "sass:color" / color.change
1.23+
Preferred module API
$whiteness / $blackness
1.28+
HWB channel sets
$space, $chroma, $x/$y/$z
1.79+
Modern spaces (oklch, lab, …)
LibSass / Ruby Sass
No module API
May expose global change-color(); prefer Dart Sass
Cheat Sheet
⚡ Quick Reference
Goal
Code
Import color
@use "sass:color";
Set red to 100
color.change($c, $red: 100)
Set lightness to 30%
color.change($c, $lightness: 30%)
Set saturation to 40%
color.change($c, $saturation: 40%)
Set hue to 200deg
color.change($c, $hue: 200deg)
Set opacity to 0.4
color.change($c, $alpha: 0.4)
Legacy global
change-color($c, $red: 100)
Compare
📋 change vs adjust vs scale
Official docs point to these three siblings for different jobs.
Red becomes exactly 100. Green and blue stay the same, so #6b717f becomes #64717f. Compare with color.adjust(..., $red: 15), which would add 15 instead.
Sass converts the hex into HSL, replaces the named channel with your exact value, then emits a new hex. Perfect when a style guide already lists the destination percentages.
📈 Practical Patterns
Exact alpha, theme ladders, and the global alias.
Example 3 — Exact Alpha and Hue
Set opacity and hue to absolute targets—not relative nudges.
One brand hex becomes a full surface ladder. Here, lightness 40% happens to match the original brand hex, while 92% and 20% create the soft fill and dark text.
Sass checks you did not mix incompatible channel families.
Validate
3
Replace channels
Each keyword overwrites its channel—no clamping.
Change
4
✓
Plain CSS color ships
Browsers receive hex, rgb, or rgba—not a Sass call.
Watch Out
⚠️ Common Pitfalls
Treating change like adjust — $red: 15 sets red to 15, it does not add 15.
Mixing RGB and HSL keywords — causes a compile error; use one family per call.
Assuming clamping — unlike adjust, change never clamps channel values.
Using $space on older Dart Sass — needs 1.79+; HSL change on hex still works without it.
Expecting relative darkening — for “20% of the way darker,” use color.scale().
Pro Tips
💡 Best Practices
✅ Do
Use @use "sass:color" and color.change() in new SCSS
Keep channel families consistent in one call
Prefer change for absolute design-token targets
Prefer Dart Sass; upgrade to 1.79+ for $space / oklch workflows
Pair with adjust / scale when the intent is relative
❌ Don’t
Pass relative deltas into change by mistake
Mix $red with $lightness in the same call
Expect the browser to re-run color.change
Rely on LibSass for sass:color
Hand-maintain dozens of hex variants you can derive
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about color.change()
Exact channel dials—set the destination, not the delta.
5
Core concepts
📝01
Call
change($color, …)
API
📦02
Module
sass:color
@use
🎨03
Does
exact values
Set
⚡04
Siblings
adjust / scale
Family
✓05
Global
change-color()
Alias
❓ Frequently Asked Questions
color.change($color, ...) replaces one or more channels with the exact values you pass and returns a new color. Example: color.change(#6b717f, $red: 100) is #64717f.
Add @use "sass:color"; then call color.change($color, $lightness: 30%) or other channel keywords. Prefer the module form in new SCSS.
change sets channels to absolute values. adjust adds or subtracts fixed amounts. scale moves channels fluidly by a percentage of the remaining room toward a bound.
No. Official Sass docs state channels are never clamped for color.change(). color.adjust() may clamp some channels that leave their native range.
The global built-in is change-color(...). On sass:color the helper is color.change(). Prefer color.change() in new code.
Built-in modules with @use need Dart Sass (about 1.23+). $whiteness/$blackness need 1.28+. $space and more modern channels need 1.79+. LibSass and Ruby Sass do not load sass:color the same way.
Did you know?
Official Sass docs recommend passing $space explicitly even for legacy colors once you are on Dart Sass 1.79+, and they highlight that color.change() never clamps channels—unlike color.adjust(), which may clamp values that leave a channel’s native range.
color.change() is the modern way to set color channels to exact values. Use it for design-token ladders, exact alpha overlays, and hue snaps; keep channel families consistent; remember it never clamps; and prefer @use "sass:color" on Dart Sass.