color.same() belongs to the built-in sass:color module. It answers: do these two colors look the same when painted? This page covers visual equality in xyz, how it differs from ==, missing channels treated as zero, the Dart Sass 1.79+ requirement, and five examples.
01
Concept
Visual equality
02
Module
@use "sass:color"
03
Space
Compares in xyz
04
Vs
== operator
05
Missing
Treated as zero
06
Practice
5 examples
Concept
What Is color.same()?
Same means “these would paint identically,” not “these are written the same way in SCSS.” Official docs return whether $color1 and $color2 visually render as the same color. A hex brand and its color.to-space(..., oklch) twin can still be same.
Reach for same after space conversions or when tokens may include none / missing channels. Reach for == when you care that the Sass values are identical as written/stored.
true if both colors visually render the same; otherwise false.
Modules
📦 Loading sass:color
There is no separate global same() built-in. Use the module form on Dart Sass 1.79+.
styles.scss
// Recommended — namespaced (Dart Sass 1.79+)
@use "sass:color";
$ok: color.same(#036, #036);
// Optional — bring members into the current namespace
@use "sass:color" as *;
$ok: same(#036, #036);
// Optional — custom namespace
@use "sass:color" as c;
$ok: c.same(#036, #036);
⚠️
Version gate
If Dart Sass reports Undefined function for color.same, upgrade to 1.79+.
Rules
🎨 How Visual Equality Works
Official docs: colors are equivalent when they represent the same color value in the xyz color space—even if they live in different spaces in your SCSS.
Situation
color.same()
Identical hex
true
Nearby but different hex (#036 vs #037)
false
Same paint, different space (hex vs oklch via to-space)
true
Missing channel vs zero (e.g. hsl(none …) vs 0deg)
true (missing ≡ zero)
Compare
📋 color.same() vs ==
Both return booleans, but they answer different questions.
Check
Question
Typical case
color.same($a, $b)
Would these look the same when painted?
Hex brand vs its oklch twin after to-space
$a == $b
Are these the same Sass color value / representation?
Strict token identity in one space
💡
Official guidance
Docs call out that same is unlike ==: different spaces can still be visually equal when their xyz values match.
Support
🛠 Compatibility
This is about Sass compilers, not browsers. The boolean is resolved at compile time—CSS never sees a color.same() call.
Feature
Dart Sass
Notes
color.same()
1.79+
Part of the modern color-spaces work
Related color.to-space()
1.79+
Often used to produce cross-space twins for comparison
Official docs: missing channels are treated as equivalent to zero for same. That keeps visual comparisons predictable when CSS none shows up after conversions.
Example 4 — Guard Duplicate Tokens
Skip emitting a second custom property when two tokens already match visually.
After to-space, you often care whether the UI still shows the same brand color. Official docs recommend same for that visual check instead of relying only on ==.
Applications
🚀 Real-World Use Cases
Token dedupe — detect when two named tokens already paint identically.
Space migrations — assert a hex brand matches its oklch twin after to-space.
Missing-channel safety — treat none like zero for visual checks.
Theme audits — flag “different” names that secretly share the same paint.
Teaching color spaces — show representation vs appearance.
🧠 How Compilation Works
1
Write SCSS
Call color.same($a, $b) after @use.
Source
2
Normalize missing
Treat missing channels as zero for the comparison.
Channels
3
Compare in xyz
Check whether both colors share the same xyz value.
Visual
4
✓
Boolean ships in CSS
Browsers receive true/false—not a Sass call.
Watch Out
⚠️ Common Pitfalls
Using only == after to-space — representation can differ while paint matches; prefer same for visual checks.
Assuming near hexes match — #036 and #037 are different colors.
Calling on older Dart Sass — needs 1.79+; expect Undefined function earlier.
Looking for a global same() — there is none; use the module form.
Forgetting missing ≡ zero — none can make same return true against a zero channel.
Pro Tips
💡 Best Practices
✅ Do
Use @use "sass:color" and color.same() on Dart Sass 1.79+
Prefer same when comparing across spaces
Pair with color.to-space() during migrations
Document whether a check is visual or representational
Upgrade the compiler before shipping modern color helpers
❌ Don’t
Expect the browser to re-run color.same
Treat same and == as interchangeable
Assume LibSass/Ruby Sass support this API
Ignore Undefined function errors—upgrade instead
Compare colors without clarifying visual vs stored equality
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about color.same()
Visual equality in xyz—not the same as ==.
5
Core concepts
📝01
Call
same($a, $b)
API
📦02
Module
sass:color
@use
🎨03
Does
visual equality
xyz
⚡04
Unlike
== operator
Strict
✓05
Needs
Dart Sass 1.79+
Version
❓ Frequently Asked Questions
color.same($color1, $color2) returns true if the two colors visually render as the same color. Example: color.same(#036, #036) is true; color.same(#036, #037) is false.
The == operator compares Sass color values more strictly by representation. color.same() treats colors as equal when they match in the xyz color space—even if one is hex and the other is oklch.
Official docs: missing channels are treated as equivalent to zero. That is why color.same(hsl(none 50% 50%), hsl(0deg 50% 50%)) is true.
Use it when comparing tokens that may live in different spaces after color.to-space(), or when none / missing channels should count as zero for visual equality.
No. Use the module form color.same() after @use "sass:color".
Did you know?
Official Sass docs compare colors in the xyz space for color.same(). That is why a hex token and its color.to-space(..., oklch) twin can still report true—the paint matches even when the SCSS representations do not.
color.same() is the visual equality check for modern Sass colors. Use it when tokens may live in different spaces, when missing channels should count as zero, and when == would be too strict—on Dart Sass 1.79+.