Sass
CSS preprocessor

Sass color.to-gamut() Function

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

What You’ll Learn

color.to-gamut() belongs to the built-in sass:color module. It maps a color into the gamut (displayable range) of a target space while keeping a visually similar result. This page covers mandatory $method (local-minde vs clip), optional $space, the Dart Sass 1.79+ requirement, and five examples.

01

Concept

Gamut mapping

02

Module

@use "sass:color"

03

Method

Mandatory

04

Options

local-minde / clip

05

Space

Optional $space

06

Practice

5 examples

What Is color.to-gamut()?

Gamut means “the colors this space can actually show.” A vivid oklch accent can sit outside the smaller rgb (sRGB) gamut. Official docs: to-gamut returns a visually similar color that fits the gamut of $space. If the color is already in-gamut, it is returned unchanged. The result always stays in $color’s original space.

  • color.to-gamut(#036, $method: local-minde)#036 (already in-gamut)
  • color.to-gamut(oklch(60% 70% 20deg), $space: rgb, $method: local-minde) → mapped oklch
  • color.to-gamut(oklch(60% 70% 20deg), $space: rgb, $method: clip) → different mapped oklch
💡
Beginner tip

Think of squeezing a wide-gamut paint chip onto an sRGB monitor. You keep the hue feeling as close as possible, but you pull chroma back until it fits.

📝 Syntax

Load the color module, then pass a color, optional space, and a required method:

styles.scss
@use "sass:color";

// Dart Sass 1.79+
// $method is mandatory: local-minde | clip
color.to-gamut($color, $space: null, $method: null)

Parameters

ParameterTypeDescription
$colorColorThe color to map (required). Result stays in this color’s space.
$spaceUnquoted stringGamut to map into (defaults to $color’s space), e.g. rgb, display-p3.
$methodUnquoted stringRequired. local-minde (CSS Colors 4 recommendation) or clip.

Return value

TypeMeaning
ColorA visually similar in-gamut color in $color’s original space (or the original color if already in-gamut).

📦 Loading sass:color

There is no separate global to-gamut() built-in. Use the module form on Dart Sass 1.79+.

styles.scss
// Recommended — namespaced (Dart Sass 1.79+)
@use "sass:color";
$safe: color.to-gamut(#036, $method: local-minde);

// Optional — bring members into the current namespace
@use "sass:color" as *;
$safe: to-gamut(#036, $method: local-minde);

// Optional — custom namespace
@use "sass:color" as c;
$safe: c.to-gamut(#036, $method: local-minde);
⚠️
Version gate

If Dart Sass reports Undefined function for color.to-gamut, upgrade to 1.79+. Always pass $method.

⚖️ local-minde vs clip

Official docs describe two mapping strategies. Prefer local-minde for most design work unless you specifically want hard channel clamping.

MethodHow it worksWhen to use
local-mindeCSS Colors 4 recommendation: binary-searches Oklch chroma until a clipped-to-gamut match is as close as possible to the reduced-chroma variant.Default choice for perceptual mapping
clipClamps each channel to the gamut minimum or maximum when out of range.Simple hard limits / comparisons
⚠️
Heads up from the docs

The CSS working group and browser vendors are still discussing the recommended gamut-mapping algorithm. Until they settle, Sass keeps $method mandatory so a future default can match CSS.

📋 to-gamut vs to-space

These helpers often work together, but they do different jobs.

HelperJobSpace of the result
color.to-gamut()Keep similar look; fit a target gamutSame as input $color
color.to-space()Convert into another color spaceThe destination $space
💡
Official pairing

Docs note that to-space into a narrower gamut can leave you with an out-of-gamut color. Follow with to-gamut when you need an in-gamut twin.

🛠 Compatibility

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

FeatureDart SassNotes
color.to-gamut()1.79+$method mandatory (local-minde / clip)
Related color.to-space()1.79+May produce out-of-gamut results; pair with to-gamut
LibSass / Ruby SassNo modern module color-space API

⚡ Quick Reference

GoalCode
Import color@use "sass:color";
Already in-gamutcolor.to-gamut(#036, $method: local-minde)
Map into rgb gamutcolor.to-gamut($c, $space: rgb, $method: local-minde)
Hard channel clipcolor.to-gamut($c, $space: rgb, $method: clip)
Prefer perceptual mapUse local-minde

Examples Gallery

Examples target Dart Sass 1.79+. Compiled outputs below match the official Sass docs samples. Open View Compiled CSS to inspect them.

📚 Getting Started

In-gamut passthrough and mapping a vivid oklch into rgb.

Example 1 — Already In-Gamut Colors Pass Through

A normal hex needs no mapping (official docs).

styles.scss
@use "sass:color";

@debug color.to-gamut(#036, $method: local-minde); // #036

.swatch {
  color: color.to-gamut(#036, $method: local-minde);
}

How It Works

Official docs: if the color is already in-gamut for the chosen space, Sass returns it as-is. No unnecessary rewrite.

Example 2 — Map Wide Oklch into the RGB Gamut (local-minde)

High chroma oklch pulled into sRGB gamut with the recommended method.

styles.scss
@use "sass:color";

// Official docs sample (Dart Sass 1.79+)
@debug color.to-gamut(
  oklch(60% 70% 20deg),
  $space: rgb,
  $method: local-minde
);
// oklch(61.2058838235% 0.2466052584 22.0773325274deg)

.accent {
  color: color.to-gamut(
    oklch(60% 70% 20deg),
    $space: rgb,
    $method: local-minde
  );
}

How It Works

The color stays in oklch (the input space), but chroma/lightness/hue are nudged so the paint fits the rgb gamut using local-minde.

📈 Practical Patterns

Clip mapping, method comparison, and sRGB-safe brand tokens.

Example 3 — Same Color with clip

Hard channel clamping produces a different mapped result (official docs).

styles.scss
@use "sass:color";

@debug color.to-gamut(
  oklch(60% 70% 20deg),
  $space: rgb,
  $method: clip
);
// oklch(62.5026609544% 0.2528579741 24.1000466758deg)

.accent-clip {
  color: color.to-gamut(
    oklch(60% 70% 20deg),
    $space: rgb,
    $method: clip
  );
}

How It Works

clip clamps out-of-range channels to the gamut edges. It is simpler and often less perceptually careful than local-minde.

Example 4 — Side-by-Side Method Comparison

Same seed color, two methods, two mapped accents.

styles.scss
@use "sass:color";

$wide: oklch(60% 70% 20deg);

.compare {
  --local-minde: #{color.to-gamut($wide, $space: rgb, $method: local-minde)};
  --clip: #{color.to-gamut($wide, $space: rgb, $method: clip)};
}

How It Works

Both fit the rgb gamut, but the channel values differ. Keep one method consistent across a design system so mapped tokens stay predictable.

Example 5 — sRGB-Safe Token from a Wide Accent

Map once, then reuse the safe token in a component palette.

styles.scss
@use "sass:color";

$accent-wide: oklch(60% 70% 20deg);
$accent-safe: color.to-gamut(
  $accent-wide,
  $space: rgb,
  $method: local-minde
);

.button {
  background: $accent-safe;
  border-color: color.to-gamut(#036, $method: local-minde);
  --source-space: #{color.space($accent-safe)};
}

How It Works

The mapped accent remains an oklch value (input space), but it now fits the rgb gamut for safer shipping to sRGB-first UIs. The hex border is already in-gamut, so it passes through.

🚀 Real-World Use Cases

  • sRGB-safe brands — map wide oklch accents before shipping hex/rgb-first sites.
  • Design-token pipelines — normalize out-of-gamut picks from Figma / display-p3 mockups.
  • After to-space — convert, then gamut-map when the destination is narrower.
  • Method A/B checks — compare local-minde vs clip for critical brand hues.
  • Print / screen handoff — pull colors into a known gamut before export.
  • Teaching color spaces — show that space conversion and gamut mapping are different steps.

🧠 How Compilation Works

1

Write SCSS

Call color.to-gamut($c, $method: …) after @use.

Source
2

Pick gamut + method

Choose $space (optional) and required local-minde or clip.

Method
3

Map or pass through

Already in-gamut colors stay put; others get a similar in-gamut twin.

Map
4

Color ships in original space

Browsers receive a finished color—still in $color’s space.

⚠️ Common Pitfalls

  • Omitting $method — it is mandatory; Sass will not guess until CSS settles a default.
  • Expecting a space changeto-gamut keeps the input space; use to-space to convert.
  • Assuming methods matchlocal-minde and clip can produce different mapped colors.
  • Calling on older Dart Sass — needs 1.79+; expect Undefined function earlier.
  • Looking for a global to-gamut() — there is none; use the module form.

💡 Best Practices

✅ Do

  • Use @use "sass:color" and color.to-gamut() on Dart Sass 1.79+
  • Prefer $method: local-minde for perceptual mapping
  • Pass $space: rgb when preparing sRGB-first CSS
  • Keep one method consistent across a token set
  • Pair with to-space when you also need a space conversion

❌ Don’t

  • Expect the browser to re-run color.to-gamut
  • Skip $method hoping for a default
  • Mix clip and local-minde randomly in one theme
  • Assume LibSass/Ruby Sass support this API
  • Confuse gamut mapping with changing the color space name

Key Takeaways

Knowledge Unlocked

Five things to remember about color.to-gamut()

Fit a gamut, keep the space, always pass $method.

5
Core concepts
📦 02

Module

sass:color

@use
🎨 03

Does

gamut mapping

Fit
04

Method

mandatory

Required
05

Needs

Dart Sass 1.79+

Version

❓ Frequently Asked Questions

color.to-gamut($color, $space: null, $method: null) returns a visually similar color that fits the gamut of $space. If the color is already in-gamut, it is returned as-is. Example: color.to-gamut(#036, $method: local-minde) is #036.
Official docs: the CSS working group is still discussing the recommended gamut-mapping algorithm. Until that settles, Sass makes $method mandatory so a future default can match CSS. Pass local-minde or clip.
local-minde is the CSS Colors 4 recommended method (binary search in Oklch chroma). clip simply clamps each channel to the gamut min/max.
No. It always returns a color in $color’s original space. $space only chooses which gamut to map into.
color.to-gamut() needs Dart Sass 1.79+. Older compilers report Undefined function.
No. Use the module form color.to-gamut() after @use "sass:color".
Did you know?

Official Sass docs keep $method mandatory on purpose: once CSS picks a default gamut-mapping algorithm, Sass can adopt the same default without silently changing old stylesheets that never declared a method.

Conclusion

color.to-gamut() is the gamut-mapping helper for modern Sass colors. Pass a mandatory $method, optionally target a gamut with $space, and remember the result stays in the input color’s space—on Dart Sass 1.79+.

Continue with color.to-space(), color.space(), or the CSS introduction.

Explore color.to-space() Next

Convert colors between spaces with the sass:color module (Dart Sass 1.79+).

Sass color.to-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.

5 people found this page helpful