Sass color.scale()

Beginner
14 min read
Updated: Nov 2026
5 examples
Preferred writer

Definition and Usage

color.scale() fluidly scales one or more channel properties of a color. Each keyword is a percent from -100% to 100%: positive moves toward the channel’s maximum, negative toward its minimum. Load it with @use "sass:color". Global alias: scale-color().

Example mental model: $lightness: 50% makes a color 50% closer to maximum lightness without jumping fully white. Official docs prefer scale over fixed helpers like lighten / darken / saturate / opacify when you want relative change.

Official samples.

color.scale(#6b717f, $red: 15%) → rgb(129.2, 113, 127). color.scale(oklch(80% 20% 120deg), $chroma: 50%, $alpha: -40%) → oklch(80% 0.24 120deg / 0.6).

Result space.

By default it scales in the color’s own space. Pass $space (Dart Sass 1.79+) to scale in another space; the returned color still stays in the original space.

Do not mix channel families.

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

Syntax

SCSS
@use "sass:color";

// RGB — percent of remaining room toward max/min
color.scale(#6b717f, $red: 15%);

// HSL-style relative moves
color.scale($brand, $lightness: 30%);
color.scale($brand, $lightness: -30%);
color.scale($brand, $saturation: 20%);

// Alpha
color.scale(rgba(#036, 0.7), $alpha: 30%);

// Other space, same origin space returned (Dart Sass 1.79+)
color.scale(#d2e1dd, $lightness: -10%, $space: oklch);
color.scale(oklch(80% 20% 120deg), $chroma: 50%, $alpha: -40%);

Pattern: @use "sass:color" → pick channel keywords as percents → scale toward the bound → use the returned color in CSS.

vs adjust / change

Three related sass:color writers:

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

Prefer scale when replacing deprecated fixed writers:

Old globalPrefer relative
lighten($c, $a)color.scale($c, $lightness: $a)
darken($c, $a)color.scale($c, $lightness: -$a)
saturate($c, $a)color.scale($c, $saturation: $a)
opacify($c, $a)color.scale($c, $alpha: …%)

SCSS Examples

Each example uses @use "sass:color". Open View Compiled CSS for verified output (matches official Sass docs samples where noted).

Example 1 — Scale an RGB Channel (Official Docs)

Move red 15% of the remaining room toward its maximum.

SCSS
@use "sass:color";

@debug color.scale(#6b717f, $red: 15%); // rgb(129.2, 113, 127)

.swatch {
  background: color.scale(#6b717f, $red: 15%);
}

How It Works

  1. Start from #6b717f.
  2. $red: 15% is not “add 15” — it is 15% of the room left to max red.
  3. Green and blue stay put.
  4. Result matches the official sample rgb(129.2, 113, 127).

Example 2 — Relative Darken Without Hitting Black

Official docs contrast this with darken(#036, 30%) → black.

SCSS
@use "sass:color";

// scale() instead makes it 30% darker than it was originally.
@debug color.scale(#036, $lightness: -30%); // #002447

.deep {
  color: color.scale(#036, $lightness: -30%);
}

How It Works

  1. #036 lightness is ~20%.
  2. Fixed darken(..., 30%) would overshoot to black.
  3. scale(..., $lightness: -30%) moves 30% toward minimum lightness.
  4. Result stays a deep navy #002447.

Example 3 — Relative Opacity (Official Docs Idea)

Make a translucent navy 30% more opaque than it was.

SCSS
@use "sass:color";

@debug color.scale(rgba(#036, 0.7), $alpha: 30%); // rgba(0, 51, 102, 0.79)

.panel {
  background: color.scale(rgba(#036, 0.7), $alpha: 30%);
}

How It Works

  1. Alpha starts at 0.7.
  2. Fixed opacify(..., 0.3) would jump to fully opaque.
  3. $alpha: 30% closes 30% of the gap toward opaque.
  4. Result is 0.79 — still translucent.

Example 4 — Scale Chroma + Alpha in Oklch (Official Docs)

Modern spaces get the same relative math.

SCSS
@use "sass:color";

@debug color.scale(oklch(80% 20% 120deg), $chroma: 50%, $alpha: -40%);
// oklch(80% 0.24 120deg / 0.6)

.accent {
  color: color.scale(oklch(80% 20% 120deg), $chroma: 50%, $alpha: -40%);
}

How It Works

  1. Chroma 20% scales 50% toward its max → 0.24.
  2. Alpha defaults to 1; -40% moves toward transparent → 0.6.
  3. Lightness and hue stay put.
  4. Needs Dart Sass 1.79+ for modern channel keywords.

Example 5 — Prefer Scale Over Lighten Trap

Official docs: pale taupe + fixed lighten becomes white; scale stays soft.

SCSS
@use "sass:color";

// #e1d7d2 has lightness ~85%, so lighten(..., 30%) becomes white.
// scale() instead makes it 30% lighter than it was originally.
@debug color.scale(#e1d7d2, $lightness: 30%); // #eae3e0

.report {
  --scale: #{color.scale(#e1d7d2, $lightness: 30%)};
}

How It Works

  1. Fixed addition on a light color overshoots to white.
  2. Relative scale keeps a soft cream #eae3e0.
  3. Same story for saturate / opacify / darken traps.
  4. Default choice for theme hover / muted / translucent states.

Edge Cases & Pitfalls

Most scale bugs are treating % like adjust amounts, or mixing RGB with HSL keywords.

intent

Percent ≠ fixed add

$lightness: 30% means “30% of remaining room toward white,” not “add 30 percentage points.”

mix

Do not mix RGB + HSL keywords

Official docs: for legacy colors, RGB and HSL (or HWB) channels cannot share one call.

space

Pass $space when you can

On Dart Sass 1.79+, explicit $space: oklch (etc.) makes relative edits predictable across gamuts.

range

Arguments stay in -100%…100%

Values outside that range are invalid. 100% jumps all the way to the bound.

Sass Support

Prefer the module form with Dart Sass and @use "sass:color".

FeatureStatus
color.scale() / scale-color()Current preferred relative writer
$whiteness / $blacknessDart Sass 1.28+
$space, $chroma, xyz channelsDart Sass 1.79+
LibSass / Ruby SassMay expose global scale-color() only

Compile with the Dart Sass CLI.

Key Takeaways

  • Relative writer: scale toward min/max by a percent of remaining room.
  • Preferred over lighten / darken / saturate / opacify for “% more” intents.
  • Use adjust for fixed steps; change for absolute values.
  • $space (1.79+) scales in another space while keeping the original space.

One line: when you mean “a bit lighter / punchier / more opaque,” reach for color.scale first.

Compile Notes

Practical checklist:

checklist.txt
1. @use "sass:color"
2. Prefer color.scale for relative theme tweaks
3. Keep keyword args between -100% and 100%
4. Do not mix RGB + HSL/HWB keywords on legacy colors
5. Pass $space on Dart Sass 1.79+ when scaling modern channels

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.

Next: Sass color.space()

Read a color’s space name as an unquoted string.

color.space() →

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