Sass color.change()

Beginner
12 min read
Updated: Nov 2026
5 examples
Compiled CSS

Definition and Usage

color.change() sets one or more channels of a color to exact new values and returns a new color. Load it with @use "sass:color". The global alias is change-color().

By default it changes channels in the color’s own space. Pass $space to edit in another space (Dart Sass 1.79+). The result always stays in the original color’s space. Official docs: channels are never clamped for color.change().

Official idea.

Replace the keyword channels with your values. Example: color.change(#6b717f, $red: 100) → #64717f.

Absolute, not relative.

$alpha: 0.4 means “set opacity to 40%,” not “subtract 0.4.” For deltas use color.adjust().

Do not mix channel families.

For legacy colors, do not change RGB and HSL (or HWB) channels in the same call. Pass $space explicitly when you can.

Syntax

SCSS
@use "sass:color";

// RGB — set exact channel
color.change(#6b717f, $red: 100);

// HSL — snap to design-token targets
color.change($brand, $lightness: 30%);
color.change($brand, $saturation: 40%);

// Alpha / hue — absolute values
color.change($brand, $alpha: 0.4);
color.change($brand, $hue: 200deg);

// Modern spaces (Dart Sass 1.79+)
color.change(#998099, $lightness: 30%, $space: oklch);

Pattern: @use "sass:color" → pick channel keywords → pass destination values → use the returned color in CSS.

vs adjust / scale

Three related sass:color writers:

FunctionWhat it doesUse when
color.change()Sets absolute channel valuesForce red=100, lightness=30%, alpha=0.4
color.adjust()Adds / subtracts fixed amountsExact steps: +15 red, +10% lightness
color.scale()Scales toward min/max by %Relative “a bit lighter / more transparent”

Quick mental model: change = set, adjust = nudge, scale = relative %.

SCSS Examples

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

Example 1 — Set an RGB Channel

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

SCSS
@use "sass:color";

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

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

How It Works

  1. Start from #6b717f.
  2. Set red to exactly 100 (not +100).
  3. Green and blue stay the same.
  4. Result is #64717f — compare with adjust, which would add a delta.

Example 2 — Set Lightness and Saturation

Snap HSL channels to design-token targets.

SCSS
@use "sass:color";

$brand: #336699;

.surface {
  color: color.change($brand, $lightness: 30%);
  background: color.change($brand, $saturation: 40%);
}

How It Works

  1. Hex converts into HSL under the hood.
  2. Lightness snaps to 30% for the text color.
  3. Saturation snaps to 40% for the background.
  4. Ideal when a style guide already lists destination percentages.

Example 3 — Exact Alpha and Hue

Set opacity and hue to absolute targets — not relative nudges.

SCSS
@use "sass:color";

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

How It Works

  1. $alpha: 0.4 means 40% opaque, not subtract 0.4.
  2. Hue snaps to 200deg for a cool accent.
  3. Other HSL channels of the outline color stay related.
  4. Absolute targets beat guessing deltas for overlays.

Example 4 — Theme Ladder from One Brand Color

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

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

  1. One brand hex drives a full surface ladder.
  2. 92% lightness creates a soft fill.
  3. 40% lightness happens to match the original brand hex.
  4. 20% lightness yields dark text.

Example 5 — Module vs Global change-color()

Both names set the same absolute channel value.

SCSS
@use "sass:color";

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

How It Works

  1. Module and global RGB changes match.
  2. Prefer color.change() so the source module is obvious.
  3. Interpolation writes the colors into custom properties.
  4. Same result as Example 1’s official red=100 sample.

Edge Cases & Pitfalls

Most color.change bugs are treating it like adjust, mixing channel families, or forgetting @use.

absolute

Values are destinations, not deltas

$red: 15 sets red to 15. To add 15, use color.adjust(..., $red: 15).

clamp

No clamping

Official docs: channels are never clamped for change. Pass values that are valid for the space constructor.

channels

Do not mix RGB with HSL/HWB

One call may not combine RGB keywords with HSL or HWB keywords on legacy colors. Use one family, or set $space.

module

Remember @use "sass:color"

Without the module load, color.change is undefined. Global change-color() still works but is less clear.

Sass Support

sass:color module loading needs Dart Sass. Prefer it for all new color work.

FeatureStatus
@use "sass:color" / color.changeDart Sass 1.23+
$whiteness / $blacknessDart Sass 1.28+
$space, $chroma, XYZ, …Dart Sass 1.79+
LibSass / Ruby SassNo module system — use global change-color() only if stuck

Compile with the Dart Sass CLI.

Key Takeaways

  • Absolute set: color.change replaces channels with exact values.
  • Load @use "sass:color" and prefer the module name.
  • Never clamped — pass valid constructor units.
  • Need deltas? Use adjust. Relative %? Use scale.

One line: color.change is how modern Sass snaps a color to exact channel targets.

Compile Notes

Conceptual flow:

flow.txt
1. @use "sass:color"
2. Resolve $color into its color space
3. Replace each keyword channel with the exact value
4. Do not clamp (unlike some adjust paths)
5. Return a new color in the original space for CSS

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.

Next: Sass color.channel()

Read one channel as a number after you set it with change.

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.

8 people found this page helpful