← Back to Sass Mastery
Intermediate13 min read

Operators & Control Flow

Use Sass math, string operators, and control directives (@if, @for, @each, @while) to generate dynamic, data-driven stylesheets.

Math Operators

Sass supports +, -, *, /, and % for numeric values with units. Use sass:math.div() for division to avoid ambiguity with CSS shorthand. Unit arithmetic follows CSS rules — adding px to rem requires care.

Math in Sass enables spacing scales, grid calculations, and responsive value generation from a single base unit.

  • Use math.div() instead of / for division in modern Sass
  • Compatible units compute: 10px + 5px = 15px
  • Incompatible units error: 10px + 1rem fails at compile time
@use 'sass:math';

$base: 0.25rem;

$space-1: $base;       // 0.25rem
$space-2: $base * 2;   // 0.5rem
$space-4: $base * 4;   // 1rem
$space-8: $base * 8;   // 2rem

.container {
  padding: $space-4;
  max-width: math.div(1200, 16) * 1rem;
}

String Operations

Sass concatenates strings with + or interpolation (#{}). Interpolation injects any Sass value into selectors, property names, or string values at compile time.

Interpolation is essential for generating utility classes, theme variants, and dynamic selector patterns from loops.

$prefix: 'btn';

.#{$prefix} {
  &--primary { background: $primary; }
  &--danger  { background: $danger; }
}

// Generates: .btn--primary, .btn--danger

@if, @else, and @else if

Conditional directives branch compilation based on expressions. Use them in mixins for responsive breakpoints, theme variants, and feature flags.

Keep conditionals in mixins and functions, not scattered through component styles. Centralizing logic makes behavior predictable and testable.

@mixin theme($mode) {
  @if $mode == 'dark' {
    background: #1e293b;
    color: #f1f5f9;
  } @else if $mode == 'light' {
    background: #ffffff;
    color: #1e293b;
  } @else {
    @error "Unknown theme: #{$mode}";
  }
}

@each and @for Loops

@each iterates over lists and maps. @for loops a range of numbers. Both generate repetitive CSS — utility classes, spacing scales, color palettes, and grid columns.

Generate design tokens programmatically from a single source list. Changing the list updates every generated class automatically.

  • @each works with lists and maps
  • @for $i from 1 through 5 includes both endpoints
  • @while loops until a condition is false — use sparingly
$colors: (
  'primary': #2563eb,
  'success': #16a34a,
  'danger':  #dc2626,
);

@each $name, $value in $colors {
  .text-#{$name} { color: $value; }
  .bg-#{$name}   { background: $value; }
}

@for $i from 1 through 12 {
  .col-#{$i} { width: math.percentage(math.div($i, 12)); }
}

Error Handling

@error stops compilation with a message — use for invalid mixin arguments. @warn outputs a warning but continues. @debug prints values to the console during compilation for troubleshooting.

Validate inputs at the top of mixins and functions. Fail fast with descriptive @error messages rather than producing broken CSS.

@function spacing($multiplier) {
  @if type-of($multiplier) != 'number' {
    @error 'spacing() expects a number, got #{type-of($multiplier)}';
  }
  @if $multiplier < 0 {
    @error 'spacing() multiplier must be positive';
  }
  @return $base-unit * $multiplier;
}

Get In Touch


Ready to discuss your next project? Drop me a message.