
Spacing Scale
- 11 installs
- 37 repo stars
- Updated December 30, 2025
- dylantarre/design-system-skills
Generates consistent spacing tokens using base values and ratios for margin, padding, and gap, output as CSS, Tailwind, or JSON.
About
This skill generates consistent spacing tokens using base values and ratios. A developer uses it to create margin, padding, and gap systems for layouts.
- Ratio-based spacing token scale
- Outputs CSS, Tailwind, or JSON
Spacing Scale by the numbers
- 11 all-time installs (skills.sh)
- Ranked #1,443 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/dylantarre/design-system-skills --skill spacing-scaleAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 11 |
|---|---|
| repo stars | ★ 37 |
| Last updated | December 30, 2025 |
| Repository | dylantarre/design-system-skills ↗ |
What it does
Generates consistent spacing tokens using base values and ratios for margin, padding, and gap, output as CSS, Tailwind, or JSON.
Files
Spacing Scale Generator
Overview
Generate consistent spacing scales using a base value and ratio. Creates exponentially distributed values centered around a base unit for harmonious layouts.
When to Use
- Setting up spacing tokens for a new project
- Standardizing padding and margin values
- Creating a gap/grid system
- Migrating from arbitrary spacing to tokens
Quick Reference
| Naming Style | Example Names | Best For |
|---|---|---|
| T-shirt | xs, sm, md, lg, xl | Semantic, readable |
| Numeric | 100, 200, 300... | Precise, extensible |
| Unit | When to Use |
|---|---|
| px | Fixed layouts, pixel-perfect designs |
| rem | Scalable, respects user font settings |
| em | Component-relative spacing |
The Process
1. Get base value: Default 4px or 0.25rem (common base unit) 2. Get ratio: How much each step grows (1.5 is balanced, 2 is dramatic) 3. Ask steps: How many spacing values (8-12 is typical) 4. Ask naming: T-shirt sizes (xs, sm, md, lg) or numeric (100, 200, 300)? 5. Ask unit: px, rem, or em? 6. Ask format: CSS, Tailwind, or JSON? 7. Generate: Create scale centered on base, expanding in both directions
Common Ratios
| Ratio | Character | Example (base 4px) |
|---|---|---|
| 1.25 | Tight | 2, 2.5, 3, 4, 5, 6, 8 |
| 1.5 | Balanced | 1.8, 2.7, 4, 6, 9, 13.5 |
| 1.618 | Golden | 1.5, 2.5, 4, 6.5, 10.5, 17 |
| 2 | Dramatic | 1, 2, 4, 8, 16, 32 |
Output Formats
CSS Custom Properties:
:root {
--spacing-xs: 2px;
--spacing-sm: 4px;
--spacing-md: 8px;
--spacing-lg: 16px;
--spacing-xl: 32px;
}Tailwind Config:
module.exports = {
theme: {
spacing: {
'xs': '2px',
'sm': '4px',
'md': '8px',
'lg': '16px',
'xl': '32px',
}
}
}JSON Tokens:
{
"spacing": {
"xs": "2px",
"sm": "4px",
"md": "8px",
"lg": "16px",
"xl": "32px"
}
}Algorithm
The scale is centered on the base value at the midpoint:
value = baseValue * (ratio ^ (step - midpoint))For a 10-step scale with base 4 and ratio 1.5:
- Step 0 (5 below mid): 4 * 1.5^-5 = 0.53
- Step 5 (midpoint): 4 * 1.5^0 = 4
- Step 9 (4 above mid): 4 * 1.5^4 = 20.25
T-shirt Size Mapping
Full range: 3xs, 2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl
The midpoint of your scale maps to "md" and expands outward.
/**
* Spacing Scale Generation Algorithm
*
* Generates consistent spacing scales using exponential ratios.
* The scale is centered on a base value, expanding in both directions.
*
* Usage:
* const tokens = generateSpacingScale(4, 1.5, 10, 'px', 'tshirt');
*/
type UnitType = 'px' | 'rem' | 'em';
type NamingStyle = 'tshirt' | 'numeric';
interface SpacingToken {
name: string;
value: number;
formatted: string;
}
/** T-shirt size names from smallest to largest */
const TSHIRT_SIZES = ['3xs', '2xs', 'xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl', '6xl'];
/**
* Generate a spacing scale.
*
* @param baseValue - The middle value of the scale (e.g., 4 for 4px)
* @param ratio - Growth ratio between steps (e.g., 1.5, 2)
* @param steps - Total number of steps to generate
* @param unit - Output unit: 'px', 'rem', or 'em'
* @param namingStyle - 'tshirt' (xs, sm, md...) or 'numeric' (100, 200, 300...)
*
* The algorithm:
* value = baseValue * (ratio ^ (step - midpoint))
*
* This centers the base value at the midpoint, with smaller values below
* and larger values above.
*/
function generateSpacingScale(
baseValue: number,
ratio: number,
steps: number,
unit: UnitType,
namingStyle: NamingStyle
): SpacingToken[] {
const tokens: SpacingToken[] = [];
const midpoint = Math.floor(steps / 2);
for (let i = 0; i < steps; i++) {
const exponent = i - midpoint;
const value = baseValue * Math.pow(ratio, exponent);
const roundedValue = Math.round(value * 100) / 100;
let name: string;
if (namingStyle === 'tshirt') {
// Map step index to t-shirt size, centering on 'md'
const sizeIndex = i + Math.max(0, 4 - midpoint);
name = TSHIRT_SIZES[sizeIndex] || `${i + 1}`;
} else {
// Numeric: 100, 200, 300...
name = String((i + 1) * 100);
}
tokens.push({
name,
value: roundedValue,
formatted: `${roundedValue}${unit}`,
});
}
return tokens;
}
// ============================================================================
// Output Formatting
// ============================================================================
/** Generate CSS custom properties */
function generateCSS(tokens: SpacingToken[], prefix = 'spacing'): string {
let css = ':root {\n';
tokens.forEach((token) => {
css += ` --${prefix}-${token.name}: ${token.formatted};\n`;
});
css += '}\n';
return css;
}
/** Generate Tailwind config */
function generateTailwind(tokens: SpacingToken[]): string {
let config = 'module.exports = {\n theme: {\n spacing: {\n';
tokens.forEach((token) => {
config += ` '${token.name}': '${token.formatted}',\n`;
});
config += ' }\n }\n}\n';
return config;
}
/** Generate JSON tokens */
function generateJSON(tokens: SpacingToken[], prefix = 'spacing'): string {
const obj: Record<string, string> = {};
tokens.forEach((token) => {
obj[`${prefix}-${token.name}`] = token.formatted;
});
return JSON.stringify({ spacing: obj }, null, 2);
}
// ============================================================================
// Common Presets
// ============================================================================
const RATIO_PRESETS = {
tight: 1.25, // Subtle progression
balanced: 1.5, // Good default
golden: 1.618, // Golden ratio
dramatic: 2, // Doubles each step (4, 8, 16, 32...)
};
export {
generateSpacingScale,
generateCSS,
generateTailwind,
generateJSON,
TSHIRT_SIZES,
RATIO_PRESETS,
type SpacingToken,
type UnitType,
type NamingStyle,
};