Chapter 11: Sass Numeric
Sass Numeric Functions — everything that lives in the sass:math module. This is where Sass handles all the serious number crunching: rounding, percentages, trigonometry, clamping, unit conversions, constants like π and e, and safe division.
In modern Dart Sass (2026 reality, version ~1.97+), you must load the module explicitly with @use ‘sass:math’; — the old global names (like round()) still work but throw deprecation warnings in recent versions. We’ll use the module style in all examples.
1. Why Numeric Functions Matter
Plain CSS has calc(), min(), max(), clamp() — great for runtime math. But Sass math happens at compile time, so you can:
- Build responsive scales (typography, spacing, etc.)
- Create modular design systems
- Convert units intelligently
- Use math constants for animations / circles
- Clamp values safely without browser support worries
Sass does unit-aware math — it knows 16px + 1rem is invalid, but 16px + 32px = 48px, and 100% / 3 needs math.div().
2. Loading the Module (Always Do This)
|
0 1 2 3 4 5 6 |
@use 'sass:math'; |
Alias if you want shorter names:
|
0 1 2 3 4 5 6 |
@use 'sass:math' as m; |
Then call math.round() or m.round().
3. The Main Numeric Functions in sass:math (2026 List)
Here are the most useful ones with playground-style examples and real-world use cases.
A. Rounding & Precision
- math.round($number) — Rounds to nearest integer math.round(4.6) → 5 math.round(4.4) → 4
- math.ceil($number) — Rounds up math.ceil(4.1) → 5
- math.floor($number) — Rounds down math.floor(4.9) → 4
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
@use 'sass:math'; $base: 16px; .spacing-1 { margin: math.round(1.3 * $base); } // 21px .spacing-2 { margin: math.ceil(1.7 * $base); } // 28px .spacing-3 { margin: math.floor(2.9 * $base); } // 46px |
Use case: Clean pixel values for consistent grids.
B. Percentage & Proportion
- math.percentage($number) — Converts unitless number to % (×100) math.percentage(0.42) → 42%
|
0 1 2 3 4 5 6 7 8 9 10 |
@use 'sass:math'; .progress-bar { width: math.percentage(3/7); // ≈ 42.857% } |
Use case: Fluid widths, opacity, flex-basis.
C. The Famous Division: math.div()
Old / is ambiguous now (can mean list separator). Always use math.div() for real division.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@use 'sass:math'; $columns: 12; .col-4 { width: math.div(4, $columns) * 100%; // 33.333% } .gap { gap: math.div(24px, 2); // 12px } |
Use case: Grid systems, aspect ratios, rem → px fallbacks.
D. Min / Max / Clamp (Compile-Time Versions)
These return the min/max/clamp value at compile time — great when values are known.
- math.min($numbers…)
- math.max($numbers…)
- math.clamp($min, $preferred, $max)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@use 'sass:math'; $fluid-font: math.clamp(14px, 3vw + 0.5rem, 24px); body { font-size: $fluid-font; } .container { max-width: math.min(1200px, 90%); } |
Use case: Typography scale, container sizes — compile-time clamp is smaller CSS than runtime clamp().
E. Trigonometry & Angles (Super Useful for Animations / Circles)
- math.sin($angle) / math.cos($angle) / math.tan($angle)
- Angles in deg, rad, turn, etc.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@use 'sass:math'; $angle: 45deg; .rotate-45 { transform: rotate($angle); } .translate-x { transform: translateX(math.sin($angle) * 100px); // ≈ 70.71px } |
Use case: Circular motion, radial gradients, custom easing paths.
F. Constants (Built-in Numbers)
- math.$pi → ≈ 3.14159
- math.$e → ≈ 2.71828
- math.$tau → ≈ 6.28318 (2π)
- math.$sqrt2 → ≈ 1.41421
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@use 'sass:math'; .circle { border-radius: math.$pi * 50%; // ≈ 157% // (makes almost perfect circle in some cases) } .golden-ratio { $phi: (1 + math.sqrt(2)) / 2; // wait, actually math.$sqrt2 is √2 ≈1.414 // Real golden is (1 + √5)/2 ≈1.618 — but you can compute it! } |
Use case: Golden ratio typography, circular progress bars, spiral animations.
G. Unit Helpers
- math.is-unitless($number) → true/false
- math.compatible($number1, $number2) → true if units can be added/subtracted
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@use 'sass:math'; @function px-to-rem($px, $base: 16px) { @if math.is-unitless($px) { @return $px / $base * 1rem; } @else { @return math.div($px, $base) * 1rem; } } |
Use case: Unit conversion helpers, responsive mixins.
H. Bounds & Safe Integers
- math.$min-safe-integer → -9007199254740991
- math.$max-safe-integer → 9007199254740991
Mostly for JS interop or very large counters.
4. Real-World Example – Modular Spacing Scale
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@use 'sass:math' as m; $base-spacing: 16px; $scale-ratio: 1.25; @function space($level) { @return m.round(m.pow($scale-ratio, $level) * $base-spacing); } .spacing-0 { margin: 0; } .spacing-1 { margin: space(0); } // 16px .spacing-2 { margin: space(1); } // ≈20px .spacing-3 { margin: space(2); } // ≈25px .spacing-4 { margin: space(3); } // ≈31px // ... |
This creates a beautiful, consistent spacing system.
5. Quick Tips & Gotchas (2026)
- Always use math.div() for division — plain / is deprecated for numbers
- Units must be compatible for + / – — Sass won’t guess
- pow() / sqrt() / trig functions expect plain numbers or angles
- For runtime math (browser-dependent) → output calc(), clamp() as strings or use native CSS
- Avoid floating-point surprises — Sass uses 64-bit floats
You’ve now got numeric superpowers! This pairs amazingly with maps (for scales), functions (for utilities), and mixins (for responsive helpers).
Next — want to build a full responsive typography system using math + clamp + pow? Or combine numeric + string functions for dynamic class names? Or dive into sass:map for theme tokens?
Just say the word — we’re making serious progress! 🚀
