EthicsComputerCourses
Join training +91 90532 10052

Operators & math.div

Sass · Lesson 8 of 26 Beginner 6 min read Updated

Sass can calculate while it compiles. You can double a spacing value, turn a column count into a percentage, or check whether one size is larger than another. The result is a plain number in your CSS, so the browser does no work at all.

In this lesson you will use the arithmetic, comparison and boolean operators, learn how units behave in maths, and learn why / no longer means division in Sass and what to use instead.

Arithmetic operators

Sass supports +, -, * and % (remainder) on numbers. Division is done with the function math.div() from the built-in sass:math module, which you load with @use "sass:math"; at the top of the file.

SCSSTry it yourself
@use "sass:math";

$base: 16px;
$columns: 12;

.layout {
  padding: $base * 1.5;
  margin-top: $base + 4px;
  gap: $base - 6;
  width: math.div(600px, 960px) * 100%;
  line-height: math.div(24px, $base);
}

.span-4 {
  flex-basis: math.percentage(math.div(4, $columns));
}
Output
.layout {
  padding: 24px;
  margin-top: 20px;
  gap: 10px;
  width: 62.5%;
  line-height: 1.5;
}

.span-4 {
  flex-basis: 33.3333333333%;
}

Look at how the units worked:

  • 16px * 1.5 keeps the px.
  • 16px - 6 treats the unitless 6 as pixels, giving 10px.
  • 600px / 960px cancels the units and leaves a plain number, which times 100% gives a percentage.
  • 24px / 16px gives a unitless 1.5, perfect for line-height.
  • math.percentage() turns a fraction into a percentage.

Units that do not mix

Sass can convert between absolute units it knows the size of, such as px, in, cm and pt. It cannot convert relative units such as em, rem, % or vw, because their real size depends on the page. Adding them is an error:

SCSSTry it yourself
.box {
  width: 100% - 2rem;
}
Output
100% and 2rem have incompatible units.
  ╷
2 │   width: 100% - 2rem;
  │          ^^^^^^^^^^^
  ╵
  - 2:10  root stylesheet

The fix is calc(). Sass understands calc(): it simplifies the parts it can, inserts your variables, and leaves the rest for the browser.

SCSSTry it yourself
$gutter: 16px;
$sidebar: 240px;

.main {
  width: calc(100% - $sidebar - $gutter * 2);
  min-height: calc(100dvh - 4rem);
}

.content {
  padding: calc(1rem + 2vw);
}
Output
.main {
  width: calc(100% - 240px - 32px);
  min-height: calc(100dvh - 4rem);
}

.content {
  padding: calc(1rem + 2vw);
}

Sass replaced the variables and worked out $gutter * 2 as 32px, then left the rest of each calc() for the browser, which knows how wide 100% really is. Variables work directly inside calc() in current Dart Sass; very old code wrote calc(100% - #{$sidebar}) with interpolation, which still works but is no longer needed.

Why / is not division any more

In CSS, / is a separator, not division: font: 16px/1.5 serif, grid-area: 1 / 3, aspect-ratio: 16 / 9 and rgb(0 0 0 / 50%). Older Sass also used / for division, and had to guess which meaning you wanted. That guessing caused bugs, so Dart Sass 1.33 deprecated / for division. Today it still divides in some places but prints a warning:

SCSSTry it yourself
$base: 16px;

.title {
  width: $base / 2;
  font: 16px/1.5 Georgia, serif;
}
Output
WARNING: Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0.

Recommendation: math.div($base, 2) or calc($base / 2)

More info and automated migrator: https://sass-lang.com/d/slash-div
    line 4
.title {
  width: 8px;
  font: 16px/1.5 Georgia, serif;
}

The plain 16px/1.5 in font was left alone as a separator, but $base / 2 divided and warned. The Sass team plans to release Dart Sass 2.0.0 around the end of 2026, and in it / outside calc() will always be a separator that builds a slash-separated list. Code like $base / 2 will then silently produce 16px/2 instead of 8px, so fix it now:

  • math.div($base, 2) for maths in Sass;
  • calc($base / 2) when you want the browser-style expression (Sass simplifies it if it can).

Comparison and boolean operators

Sass compares values with ==, !=, <, <=, > and >=, and combines true/false values with and, or and not. You will use these mostly inside @if rules (Control Flow) and functions:

SCSSTry it yourself
$base: 16px;
$columns: 12;
$dark-theme: false;

.debug {
  a: $base == 16px;
  b: 2rem > 1rem;
  c: 1px * 3 != 3px;
  d: ($columns > 10) and ($base < 20px);
  e: not $dark-theme;
  f: $dark-theme or ($columns == 12);
}
Output
.debug {
  a: true;
  b: true;
  c: false;
  d: true;
  e: true;
  f: true;
}

The property names a to f are just labels so you can see the results in the output; real code would use these inside @if. Note that < and > only work on numbers with compatible units, and == compares the value and unit: 16px == 1rem is false.

String operators

+ also joins strings. If the first string is quoted, the result is quoted:

SCSSTry it yourself
$city: "Pune";

.label::before {
  content: $city + " Metro, Line 1";
  font-family: "Noto Sans" + ", sans-serif";
}
Output
.label::before {
  content: "Pune Metro, Line 1";
  font-family: "Noto Sans, sans-serif";
}

The first line is what you wanted. The second is a trap: the result is one quoted string, "Noto Sans, sans-serif", which the browser reads as a single font name that does not exist. A font list is a comma-separated list, so write it directly: font-family: "Noto Sans", sans-serif;. For anything more than joining, use Interpolation or the sass:string module.

Common mistakes

  • $a / $b for division. It warns now and will mean something else in Dart Sass 2. Use math.div($a, $b).
  • Mixing % or rem with px outside calc(). Sass cannot know the size; use calc() and let the browser do it.
  • Forgetting @use "sass:math";. Without it, math.div is an unknown function and the call is left as plain text.
  • Comparing values with different units. 10px > 2em is an error, because Sass cannot convert em.

Key points

  • +, -, * and % work on numbers; units multiply, cancel and convert when Sass knows their size.
  • Divide with math.div() from sass:math; / for division is deprecated and becomes a separator in Dart Sass 2.
  • Relative units (%, em, rem, vw) cannot mix with px at compile time; use calc(), which accepts Sass variables directly.
  • ==, !=, <, > and friends compare values; and, or and not combine booleans.
  • + joins strings; a quoted first string gives a quoted result.

Exercise

A Jaipur textile shop's product grid is 1140px wide with 4 columns and a 24px gap. Using sass:math, calculate each column's width in pixels ((1140px - 3 * 24px) / 4) and as a percentage of the grid. Set .col with width as the percentage and max-width as the pixel value, and .grid with gap and a width of calc(100% - 2rem). Do not use / for division.

Show solution
SCSS
@use "sass:math";

$grid: 1140px;
$columns: 4;
$gap: 24px;
$col-px: math.div($grid - ($columns - 1) * $gap, $columns);

.grid {
  gap: $gap;
  width: calc(100% - 2rem);
}

.col {
  width: math.percentage(math.div($col-px, $grid));
  max-width: $col-px;
}

$col-px works out to 267px, and dividing it by 1140px cancels the units, so math.percentage() gives about 23.42%.

Quick Quiz

1. Which is the modern way to divide $width by 2?

2. What happens to 100% - 2rem outside calc()?

3. In Dart Sass 2, what will 16px / 2 outside calc() produce?

4. What does math.div(24px, 16px) return?

Learn Sass with a mentor

Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call