iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

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.

Example

Example
$base: 16px;
.p-2 { padding: $base * 2; }
.gap-half { gap: $base / 2; }
Try it Yourself »

Discussion

Loading…