Spacing & Typography Scale Generators
Generate a modular type scale and a consistent spacing scale from a ratio and a base — no magic numbers.
Consistent design comes from scales, not from typing pixel values by feel. A modular scale multiplies a base size by a ratio at each step; a spacing scale does the same for whitespace. Generate both from two variables and every value in your system is related by math.
A modular type scale
Pick a base (16px) and a ratio (1.25, the 'major third'). Each step up multiplies by the ratio; each step down divides. math.pow() makes this a one-liner.
@use 'sass:math';
@function step($n, $base: 1rem, $ratio: 1.25) {
@return $base * math.pow($ratio, $n);
}
.h2 { font-size: step(3); } // ~1.95remWhy generate it?
- One place to retune the whole system — change the ratio, everything reflows.
- No off-scale one-offs sneaking in.
- The output can be Sass values or emitted custom properties for runtime use.
Example
@use 'sass:math';
@use 'sass:map';
$type-base: 1rem;
$type-ratio: 1.25; // major third
$type-steps: (-1, 0, 1, 2, 3, 4, 5);
// Modular type scale -> custom properties
@function modular($n) {
@return $type-base * math.pow($type-ratio, $n);
}
:root {
@each $n in $type-steps {
--fs-#{$n}: #{modular($n)};
}
}
// Geometric spacing scale (4px base, doubling)
$space-base: 0.25rem;
$space-map: ();
@for $i from 0 through 6 {
$space-map: map.set($space-map, $i, $space-base * math.pow(2, $i));
}
:root {
@each $k, $v in $space-map {
--space-#{$k}: #{$v};
}
}
.card { padding: var(--space-3); font-size: var(--fs-1); }
.card__title { font-size: var(--fs-3); }When to use it
- A design system generates its entire 9-step type scale from a single base size and a ratio using Sass math, eliminating all hand-picked font-size values.
- A developer produces a spacing scale from a base unit and a multiplier list so changing the base unit scales every component's padding and margin proportionally.
- A team exports both the computed scale values as Sass variables and as CSS custom properties so Sass partials and raw CSS files can both consume them.
More examples
Modular type scale generator
Generates a 6-step type scale map by applying a modular ratio exponent to the base size for each scale step using math.pow().
@use 'sass:math';
$base: 1rem;
$ratio: 1.25; // major third
$steps: (-1, 0, 1, 2, 3, 4);
$type-scale: ();
@each $n in $steps {
$type-scale: map-merge($type-scale,
(#{$n}: $base * math.pow($ratio, $n)));
}
// Keys: -1, 0, 1, 2, 3, 4 Values: 0.8rem … 2.44remSpacing scale from base unit
Multiplies a 4px base unit by each step in the multiplier list to emit a complete spacing scale as CSS custom properties.
@use 'sass:math';
$base-space: 4px;
$multipliers: 1, 2, 3, 4, 6, 8, 12, 16, 24;
:root {
@each $m in $multipliers {
--space-#{$m}: #{$base-space * $m};
}
}Applying generated scale to headings
Applies scale values to heading elements and derives proportional line-heights from each font size using math operations.
@use 'sass:math';
@use 'sass:map';
$scale: (h1: 2.441rem, h2: 1.953rem, h3: 1.563rem, h4: 1.25rem, h5: 1rem);
@each $tag, $size in $scale {
#{$tag} {
font-size: $size;
line-height: math.div(math.round($size * 16 * 1.3), 16) * 1rem;
}
}
Discussion