Sass color.change() Function

Beginner
⏱️ 14 min read
📚 Updated: Jul 2026
🎯 5 Examples
sass:color · Dart Sass

What You’ll Learn

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

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.

  • color.change(#6b717f, $red: 100)#64717f
  • color.change(#336699, $lightness: 30%)#264d73
  • color.change(#4caf50, $alpha: 0.4)rgba(76, 175, 80, 0.4)
💡
Beginner tip

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.

📝 Syntax

Load the color module, then call the function with keyword channel arguments:

styles.scss
@use "sass:color";

color.change($color,
  $red: null, $green: null, $blue: null,
  $hue: null, $saturation: null, $lightness: null,
  $whiteness: null, $blackness: null,
  $alpha: null
  // Dart Sass 1.79+: also $space, $chroma, $x, $y, $z, ...
)

Common parameters

ParameterTypeDescription
$colorColorThe starting color to change (required).
$red / $green / $blueNumberSet RGB channels to these exact values (typically unitless 0–255 for legacy RGB).
$hueAngleSet hue to this angle (for example 200deg).
$saturation / $lightnessPercentageSet HSL saturation or lightness to this exact %.
$whiteness / $blacknessPercentageSet HWB channels (Dart Sass 1.28+).
$alphaNumberSet opacity to this exact value (for example 0.4).
$spaceColor space nameChange channels in another space (Dart Sass 1.79+), e.g. hsl, oklch.

Return value

TypeMeaning
ColorA new color in the same space as $color, with the requested channels replaced. Official docs: channels are never clamped for color.change().

📦 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+).

🎨 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.

OK together?Example
Yes — RGB familycolor.change($c, $red: 100, $blue: 50)
Yes — HSL familycolor.change($c, $hue: 200deg, $lightness: 30%)
Yes — alpha with eithercolor.change($c, $lightness: 40%, $alpha: 0.8)
No — RGB + HSLcolor.change($c, $red: 100, $lightness: 30%) → error
💡
Modern tip (Dart Sass 1.79+)

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.

⚠️ 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.

HelperClamping?When to prefer it
color.change()NeverYou need an exact channel value from a design token
color.adjust()Some channels may clampYou 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.”

🛠 Compatibility

This is about Sass compilers, not browsers. Compiled CSS receives a finished color—no color.change() call remains.

FeatureDart SassNotes
@use "sass:color" / color.change1.23+Preferred module API
$whiteness / $blackness1.28+HWB channel sets
$space, $chroma, $x/$y/$z1.79+Modern spaces (oklch, lab, …)
LibSass / Ruby SassNo module APIMay expose global change-color(); prefer Dart Sass

⚡ Quick Reference

GoalCode
Import color@use "sass:color";
Set red to 100color.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 200degcolor.change($c, $hue: 200deg)
Set opacity to 0.4color.change($c, $alpha: 0.4)
Legacy globalchange-color($c, $red: 100)

📋 change vs adjust vs scale

Official docs point to these three siblings for different jobs.

HelperWhat it doesMental model
color.change()Set channels to exact values“Make lightness exactly 30%”
color.adjust()Add/subtract fixed amounts“Plus 10% lightness”
color.scale()Scale toward a bound by a %“Move 20% of the way lighter”
styles.scss
@use "sass:color";

$brand: #336699;

// Absolute target
$exact: color.change($brand, $lightness: 30%);

// Relative nudge (+10% from current)
$nudge: color.adjust($brand, $lightness: 10%);

// Prefer scale when you want proportional darkening/lightening
// $fluid: color.scale($brand, $lightness: -20%);

🎯 When to Prefer change

Reach for color.change() when the design system already knows the destination value—not how far to travel from the current color.

SituationPrefer
“Surfaces use lightness 92% / 40% / 20%”color.change(..., $lightness: ...)
“Make this overlay exactly 40% opaque”color.change(..., $alpha: 0.4)
“Snap hue to 200deg for the info accent”color.change(..., $hue: 200deg)
“10% lighter than brand”color.adjust(..., $lightness: 10%)
“20% of the way toward white/black”color.scale(...)

Examples Gallery

Each example uses @use "sass:color". Open View Compiled CSS to see what Dart Sass emits.

📚 Getting Started

Official-style RGB set and everyday HSL targets.

Example 1 — Set an RGB Channel

Replace red with an exact value (official docs example).

styles.scss
@use "sass:color";

@debug color.change(#6b717f, $red: 100); // #64717f

.swatch {
  background: color.change(#6b717f, $red: 100);
}

How It Works

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.

Example 2 — Set Lightness and Saturation

Snap HSL channels to design-token targets.

styles.scss
@use "sass:color";

$brand: #336699;

.surface {
  color: color.change($brand, $lightness: 30%);     // #264d73
  background: color.change($brand, $saturation: 40%); // #3d668f
}

How It Works

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.

styles.scss
@use "sass:color";

.overlay {
  color: color.change(#4caf50, $alpha: 0.4);
  outline-color: color.change(#c65353, $hue: 200deg);
}

How It Works

$alpha: 0.4 means “40% opaque,” not “subtract 0.4.” Hue snaps to 200deg, inventing a cool accent while keeping the other HSL channels.

Example 4 — Theme Ladder from One Brand Color

Build surface, border, and text colors by setting known lightness steps.

styles.scss
@use "sass:color";

$brand: #336699;

.card {
  background: color.change($brand, $lightness: 92%);
  border-color: color.change($brand, $lightness: 40%);
  color: color.change($brand, $lightness: 20%);
}

How It Works

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.

Example 5 — Module vs Global change-color()

Both names set the same absolute channel value.

styles.scss
@use "sass:color";

.names {
  --module: #{color.change(#6b717f, $red: 100)};
  --global: #{change-color(#6b717f, $red: 100)};
}

How It Works

Module and global RGB changes match. Prefer color.change() so readers see the helper comes from sass:color.

🚀 Real-World Use Cases

  • Design-token ladders — set known lightness steps for surface / text / border.
  • Exact overlays — force alpha to 0.2, 0.4, or 0.8 for scrims and chips.
  • Accent snaps — set hue to a fixed angle for info, success, or warning accents.
  • Saturation resets — dial saturation to a brand percentage without math on the current value.
  • Component themes — keep one brand hex and derive every role with absolute channels.
  • Migration clarity — replace hand-picked hex tables with explicit change calls.

🧠 How Compilation Works

1

Write SCSS

Call color.change($color, ...) after @use.

Source
2

Validate channels

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.

⚠️ 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().

💡 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

Key Takeaways

Knowledge Unlocked

Five things to remember about color.change()

Exact channel dials—set the destination, not the delta.

5
Core concepts
📦 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.

Conclusion

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.

Continue with color.channel(), color.adjust(), or the CSS introduction.

Explore color.channel() Next

Read color channels as numbers with the sass:color module (Dart Sass 1.79+).

Sass color.channel() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful