CSS Spacing Scale Generator
Turn a base size and a ratio into a full spacing scale of CSS custom properties.
About the CSS Spacing Scale Generator
The scale is built by raising the ratio to increasing powers around a middle step: the step at the center equals the base size exactly, steps below it shrink by dividing by the ratio, and steps above it grow by multiplying by the ratio, each result rounded to the nearest pixel. That keeps the whole scale proportional instead of just adding a fixed amount each time, so larger gaps feel deliberately bigger rather than just further down a list.
Why a geometric scale beats simply adding a fixed amount each step
The simplest possible spacing scale just adds a constant, 8px, 16px, 24px, 32px, and so on. The problem is that a fixed increment feels enormous relative to a small base value but nearly invisible relative to a large one, the jump from 8px to 16px doubles the space, while the jump from 96px to 104px barely registers. A geometric (ratio-based) scale instead multiplies by a constant factor at every step, so each jump is proportionally the same size relative to where it started. This is the exact same principle behind modular type scales for font sizing, and it's why design systems that need spacing to feel visually consistent at every size, not just numerically increasing, favor this exponential approach over flat addition.
Why the base value doesn't always land exactly in the middle
The scale is centered using Math.floor(steps / 2) as the middle index, and your base size lands exactly at that position with an exponent of zero. For an odd step count like 7, that split works out evenly, three steps shrink below the base and three steps grow above it. But for an even step count like 6, flooring the division means the base size sits at index 3, which puts three steps below it and only two steps above it, a subtle asymmetry worth knowing if you're expecting your base value to be perfectly centered in the generated list.
Two different naming conventions, and when to use each
The Numbered scheme (xs, sm, md, lg, xl, 2xl...) is the convention used by utility-first frameworks and many component libraries, it reads intuitively without needing to know the underlying pixel value. The Numeric scheme (space-1, space-2, space-3...) avoids implying any particular size association, useful if your team prefers referencing scale position rather than a size label, or if you expect the scale to grow well beyond what t-shirt sizes can clearly represent (there's a limit to how intuitive "6xl" reads compared to "space-10"). Neither is objectively better, the choice mostly comes down to what naming convention the rest of your design system or codebase already uses.
Why this outputs CSS custom properties instead of Sass variables
Writing the scale as :root { --space-md: 24px; } rather than a Sass or Less variable means the values are available at runtime in the browser, not just compiled away at build time. That matters for real design system work: a component can override just one spacing variable locally (redefining --space-md inside a denser, data-heavy table component, for instance) without needing a build step or a separate stylesheet, and the same scale can be swapped per theme or per breakpoint using nothing more than CSS's normal cascade and specificity rules.
Where the preset ratio names come from
The preset dropdown borrows its labels from modular scale terminology popularized in typography and design-system tooling, itself borrowed from musical interval names, the idea being that ratios which sound pleasant as musical intervals also tend to produce visually pleasant proportional relationships. The Golden Ratio (1.618) is the most recognizable of the set, showing up across design and nature discussions for its historically claimed aesthetic appeal, while ratios like 1.25 and 1.333 tend to produce a noticeably tighter, more restrained scale suited to dense interfaces, and 1.5 or 1.618 produce a much more dramatic spread better suited to marketing pages or spacious editorial layouts.
Frequently Asked Questions
Why use a ratio-based scale instead of just adding a fixed pixel amount each step?
A fixed increment feels huge relative to small values and negligible relative to large ones. A ratio-based scale multiplies by the same factor at every step, so each jump is proportionally consistent regardless of where it falls in the scale, which reads as more visually balanced.
Does my base size always land exactly in the middle of the generated scale?
Only when the step count is odd. For an even step count, the middle index is calculated with Math.floor(steps / 2), which places the base value slightly left of center, with one more step below it than above it.
Should I use the Numbered (xs, sm, md) or Numeric (space-1, space-2) naming scheme?
Numbered names read intuitively and match common utility-first framework conventions, while Numeric names avoid implying a specific size and scale more cleanly if you expect many steps. Neither is objectively better, it depends on your existing codebase's naming conventions.
Why does this generate CSS custom properties instead of Sass or Less variables?
CSS custom properties are available at runtime in the browser, not compiled away at build time, so individual components or themes can override a single spacing value locally using CSS's normal cascade, without needing a build step or separate stylesheet.
Are the scale values rounded, and does that rounding compound across steps?
Each value is rounded to the nearest pixel, but every step is calculated fresh from the base size and its own exponent, not by repeatedly multiplying the previous rounded step. That means rounding error doesn't accumulate or drift across the scale.
What's a reasonable number of steps for a typical project's spacing scale?
Between 5 and 8 steps covers most real interfaces well, enough range to distinguish tight inline spacing from large section padding, without so many steps that the scale becomes hard to remember or apply consistently across a team.