Operators
Sass operators handle arithmetic, color blending, equality, logical combinators — at compile time. Use for spacing math, color tweaks, conditionals in mixins. Note: / is now division via math.div().
Math, color, comparison, logical
EXAMPLE
@@use 'sass:math';
@@use 'sass:color';
/* === 1. Arithmetic operators === */
/* Addition + subtraction */
.foo { margin: 1rem + 0.5rem; } /* 1.5rem */
.bar { padding: 2rem - 1rem; } /* 1rem */
/* Multiplication */
.baz { font-size: 1rem * 1.25; } /* 1.25rem */
/* Division — REQUIRES math.div() in modern Sass */
.qux { width: math.div(960, 12); } /* 80px */
.aspect { aspect-ratio: math.div(16, 9); } /* 1.7778 */
/* Modulo (remainder) */
.foo { z-index: 10 % 7; } /* 3 */
/* Operators work with unit conversion */
.foo { width: 100% - 20px; } /* calc(100% - 20px) — auto-wrapped */
.bar { width: 50vw + 10px; } /* calc(50vw + 10px) */
/* === 2. Unit math === */
/* Compatible units — direct */
.foo { width: 10px + 5px; } /* 15px */
/* Different units that convert */
.bar { font-size: 1in + 6pt; } /* 1.0833in */
/* Incompatible units — wrap in calc() */
.baz { width: 100% - 2em; } /* calc(100% - 2em) */
/* === 3. Building a spacing scale via operators === */
$base: 0.25rem;
@@for $i from 0 through 12 {
.m-#{$i} { margin: $base * $i; } /* 0, 0.25rem, 0.5rem, ... */
.p-#{$i} { padding: $base * $i; }
}
/* === 4. Typography ratio === */
$base-size: 1rem;
$ratio: 1.25; /* major third */
.text-sm { font-size: $base-size / $ratio; } /* DEPRECATED — use math.div */
.text-sm-2 { font-size: math.div($base-size, $ratio); }
.text-lg { font-size: $base-size * $ratio; }
.text-xl { font-size: $base-size * $ratio * $ratio; }
/* === 5. Color math (deprecated +/- on colors) === */
/* DEPRECATED — direct + / - on colors */
/* $primary: #0ea5e9;
.hover { background: $primary - #111; } */
/* MODERN — color module */
$primary: #0ea5e9;
.hover { background: color.adjust($primary, $lightness: -10%); }
.dim { background: color.scale($primary, $lightness: -30%); }
.alpha { background: color.adjust($primary, $alpha: -0.5); }
.shift { background: color.adjust($primary, $hue: 30deg); }
.mix { background: color.mix($primary, white, 70%); }
/* === 6. Comparison operators === */
$value: 5;
@@if $value > 4 { .lg { font-size: 1.5rem; } }
@@if $value < 10 { .ok { color: green; } }
@@if $value >= 5 { .big { font-weight: bold; } }
@@if $value <= 5 { .same { opacity: 0.8; } }
@@if $value == 5 { .exact { color: red; } }
@@if $value != 10 { .different { color: blue; } }
/* === 7. Logical operators === */
$x: 5;
$y: true;
@@if $x > 0 and $x < 10 { /* both true */ }
@@if $y or $x == 5 { /* either true */ }
@@if not $y { /* negation */ }
/* === 8. String concatenation === */
$prefix: 'icon-';
$name: 'home';
.foo { content: $prefix + $name; } /* 'icon-home' */
/* Or use interpolation */
.foo { content: '#{$prefix}#{$name}'; }
/* === 9. Conditional output in mixins === */
@@mixin theme($mode) {
@@if $mode == 'dark' {
background: #0b0b0b;
color: #eee;
} @@else if $mode == 'light' {
background: #fff;
color: #111;
} @@else {
@@error "Unknown theme: #{$mode}";
}
}
/* === 10. Real-world examples === */
/* a) Negative margin for offset */
.container { padding: 1rem; }
.row { margin: 0 (-1rem); } /* extend to padding edges */
/* b) Stripe pattern */
@@for $i from 1 through 5 {
.stripe:nth-child(#{$i}) {
opacity: math.div($i, 5);
}
}
/* c) Generate utility classes */
$colors: ('primary': #0ea5e9, 'success': #10b981, 'danger': #ef4444);
@@each $name, $value in $colors {
.bg-#{$name} { background: $value; }
@@for $shade from 1 through 9 {
.bg-#{$name}-#{$shade * 100} {
background: color.adjust($value, $lightness: (5 - $shade) * 5%);
}
}
}
/* === 11. Common bugs === */
/* • Using / for division — silently treated as separator in some contexts */
/* Fix: math.div(a, b) */
/* • Mixing incompatible units without calc */
/* Fix: Sass wraps in calc() if it can; otherwise error */
/* • Direct +/- on colors — deprecated; use color module */
/* • Forgetting interpolation when building selectors */
/* $class: 'foo'; .#{$class} { ... } // works */
/* .$class { ... } // doesn't */
/* === 12. Migration from older Sass === */
/* Old: */
/* $width: 100 / 12; /* DEPRECATED */
/* .col { width: $width * 1%; } /* width: 8.3333% */
/* New: */
$width: math.div(100, 12);
.col { width: $width * 1%; }
/* === 13. Best practices === */
/* ✅ Use math.div() for division */
/* ✅ Use color module functions, not + / - on colors */
/* ✅ Comparison + logic for build-time conditionals */
/* ✅ Comment why if math isn't obvious */
/* ✅ Prefer @use over @import (loads modules with namespaces) */
/* ✅ Use unit-aware functions — math.div(strip-unit($x), strip-unit($y)) when needed */
Why it matters
Sass operators run at compile time — perfect for scaling design tokens, generating utility classes, or theme math. Use math.div() for division (the / operator is now a separator in lots of contexts).
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Discussion
Loading…