Sass color.grayscale()

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

Definition and Usage

color.grayscale() returns a gray with the same lightness as $color. Load it with @use "sass:color". The global alias is grayscale().

Official docs: for legacy colors it sets HSL saturation to 0%; otherwise it sets Oklch chroma to 0%. The result stays in the original color’s space.

Official idea.

color.grayscale(#6b717f) → #757575. Modern: color.grayscale(oklch(50% 80% 270deg)) → oklch(50% 0% 270deg).

Not the CSS filter.

Sass compiles to a finished gray color. CSS filter: grayscale() is a runtime effect on an element or image.

Full mute, not a partial step.

For “a bit quieter,” prefer color.scale($c, $saturation: -$amount). Deprecated desaturate() subtracts a fixed amount and can overshoot.

Syntax

SCSS
@use "sass:color";

// Legacy hex — HSL saturation → 0%
color.grayscale(#6b717f); // #757575

// Modern spaces — Oklch chroma → 0%
color.grayscale(oklch(50% 80% 270deg)); // oklch(50% 0% 270deg)

// Global alias
grayscale(#6b717f);

Pattern: @use "sass:color" → pass a brand color → use the gray twin for disabled / secondary UI.

vs CSS Filter / desaturate

Related ways to mute color:

ApproachWhat it doesUse when
color.grayscale()Compile-time gray color valueTokens, disabled fills, borders
CSS filter: grayscale()Runtime visual filterPhotos, icons, whole elements
color.scale(..., $saturation: -…)Relative % quieterPartial mute, keep some tint
desaturate()Deprecated fixed subtractLegacy SCSS only

SCSS Examples

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

Example 1 — Official Hex Grayscale

Convert the docs sample color to gray.

SCSS
@use "sass:color";

@debug color.grayscale(#6b717f); // #757575

.swatch {
  background: color.grayscale(#6b717f);
}

How It Works

  1. Hex is legacy, so Sass uses the HSL path.
  2. Saturation snaps to 0%; lightness stays.
  3. Result matches the official sample #757575.
  4. No grayscale() call remains in the CSS.

Example 2 — Mute Several Brand Hexes

Derive neutral twins from blue, green, and red tokens.

SCSS
@use "sass:color";

.muted {
  color: color.grayscale(#336699);         // #666666
  background: color.grayscale(#4caf50);    // #7e7e7e
  outline-color: color.grayscale(#c65353); // #8d8d8d
}

How It Works

  1. Each brand keeps its relative brightness as gray.
  2. Darker originals become darker neutrals.
  3. Useful for disabled and secondary UI states.
  4. No hand-picked gray hex needed per brand.

Example 3 — Disabled Theme from One Brand

Keep the live brand colorful; desaturate copies for inactive UI.

SCSS
@use "sass:color";

$brand: #336699;
$brand-muted: color.grayscale($brand);

.button {
  background: $brand;
  color: #fff;
}

.button:disabled {
  background: $brand-muted; // #666666
  color: #fff;
  border-color: color.grayscale(#2196f3); // #8a8a8a
}

How It Works

  1. One brand token drives the live fill.
  2. $brand-muted is the gray twin for disabled.
  3. Border can mute a different accent the same way.
  4. Design system stays DRY — no second hand-picked gray.

Example 4 — Sass Color vs CSS Filter

Use both APIs in one stylesheet — know which is which.

SCSS
@use "sass:color";

.chip {
  // Sass: compile-time gray color value
  color: color.grayscale(#336699);
}

.photo.is-muted {
  // CSS: runtime filter on the element (not a Sass color helper)
  filter: grayscale(1);
}

How It Works

  1. color.grayscale() becomes a hex in the CSS file.
  2. filter: grayscale(1) stays a CSS filter for the browser.
  3. Chip text is a gray token; the photo is filtered at paint time.
  4. Prefer the module name so readers do not confuse the two APIs.

Example 5 — Module vs Global grayscale()

Both names produce the same gray for legacy colors.

SCSS
@use "sass:color";

.names {
  --module: #{color.grayscale(#6b717f)};
  --global: #{grayscale(#6b717f)};
}

How It Works

  1. Module and global grayscale matches for legacy hex.
  2. Prefer color.grayscale() so the source module is obvious.
  3. Avoid confusion with CSS filter: grayscale().
  4. Same result as Example 1’s official sample.

Edge Cases & Pitfalls

Most color.grayscale bugs are confusing it with the CSS filter, or wanting a partial mute.

filter

Sass ≠ CSS filter

Write color.grayscale($c) for tokens. Use filter: grayscale(1) only for runtime visual effects.

partial

All or nothing

Grayscale fully mutes. For “a bit quieter,” use color.scale(..., $saturation: -30%).

already gray

Gray in, gray out

Calling grayscale on a near-gray color barely changes the look — lightness is already the story.

module

Remember @use

Without @use "sass:color", color.grayscale is undefined. Global grayscale() still works but is less clear.

Sass Support

Module form needs Dart Sass. Prefer it for all new grayscale work.

FeatureStatus
@use "sass:color" / color.grayscaleDart Sass 1.23+
Global grayscale()Older compilers / legacy SCSS
Modern spaces (Oklch chroma path)Dart Sass with modern color support
LibSass / Ruby SassNo modern module API

Compile with the Dart Sass CLI.

Key Takeaways

  • Gray twin: same lightness, no saturation / chroma.
  • Load @use "sass:color" and prefer the module name.
  • Not CSS filter — this emits a finished color.
  • Partial mute? Use color.scale, not grayscale.

One line: color.grayscale is how modern Sass derives a same-lightness gray token from any brand color.

Compile Notes

Conceptual flow:

flow.txt
1. @use "sass:color"
2. Resolve $color
3. Legacy → HSL saturation 0% | Modern → Oklch chroma 0%
4. Keep lightness (and space)
5. Emit a finished gray CSS color — no grayscale() left

Frequently Asked Questions

color.grayscale($color) returns a gray color with the same lightness as $color. Example: color.grayscale(#6b717f) is #757575.
Add @use "sass:color"; then call color.grayscale($brand). Prefer the module form in new SCSS. The global alias is grayscale().
Official docs: for legacy colors it sets HSL saturation to 0%. For non-legacy colors it sets Oklch chroma to 0%.
No. Sass color.grayscale() compiles to a finished gray color (hex/rgb). CSS filter: grayscale() is a runtime visual effect on an element or image.
color.adjust($c, $saturation: -100%) can also mute legacy colors, but color.grayscale() is the dedicated helper and also covers modern spaces by zeroing Oklch chroma.
The module form needs Dart Sass with @use (about 1.23+). LibSass/Ruby Sass may expose a global grayscale() but lack the modern module API.

Next: Sass color.ie-hex-str()

Format a color as #AARRGGBB for legacy IE -ms-filter.

color.ie-hex-str() →

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