Understanding the Typography & Spacing System
One of the most critical aspects of any design system is how it handles typography and spacing. Too often, these systems become a collection of arbitrary values that designers and developers struggle to understand and maintain. This post documents the mathematical foundation behind our typography and spacing system, explaining how every value relates to create a harmonious, scalable design.
The Foundation: Two Single Sources of Truth
Our entire system is built on two foundational decisions that cascade through every element:
1. Base Typography: The Fluid Type Scale
Rather than fixed font sizes, we use a fluid type system that smoothly scales between mobile and desktop viewports. This ensures optimal readability at every screen size without jarring breakpoint jumps.
// In tailwind.config.ts
"0": {
minSize: "0.94rem", // 15px on mobile (320px)
maxSize: "1.06rem", // 17px on desktop (1280px)
lineHeight: "1.60" // 160% for optimal readability
}
This base size (text-0
) is our body text. All other sizes scale proportionally using a 1.25 ratio (musical major third):
Class | Mobile | Desktop | Usage |
---|---|---|---|
text--2 | 10px | 12px | Tiny captions |
text--1 | 13px | 14px | Small text |
text-0 | 15px | 17px | Body text (base) |
text-1 | 19px | 21px | Large text |
text-2 | 23px | 27px | H3 headings |
text-3 | 29px | 33px | H2 headings |
text-4 | 37px | 41px | H1 headings |
text-5 | 46px | 52px | Display |
text-6 | 57px | 65px | Hero |
Key insight: Changing the base size in the config automatically scales the entire typography system proportionally.
2. Spatial Rhythm: The 6px Grid
Our spacing system is built on a 6px grid unit that creates a 24px baseline (matching 1.5 × 16px base font size):
/* In global.css */--baseline: 1.5rem; /* 24px = 16px × 1.5 */--grid-unit: 0.375rem; /* 6px = 24px ÷ 4 */
Why 6px? It’s the perfect divisor:
- 24px baseline ÷ 4 = 6px (clean grid alignment)
- Allows half-line spacing (12px = 2 units)
- More flexible than 4px or 8px for typography
- Creates natural spacing progression
The complete spacing scale:
How It All Works Together
Vertical Rhythm
Every element aligns to the 24px baseline, creating a invisible grid that guides the eye:
/* Paragraphs */
p {
line-height: 1.5; /* 24px baseline */
margin-bottom: var(--space-4); /* 24px = 1 baseline */
}
/* Headings */
h2 {
margin-top: var(--space-8); /* 48px = 2 baselines */
margin-bottom: var(--space-2); /* 12px = 0.5 baseline */
}
Using the System in Practice
The beauty of this system is its simplicity. In Tailwind, you use semantic spacing utilities:
<!--Using grid-based spacing-->
<div class="p-4"> <!--24px padding-->
<h2 class="mb-2"> <!--12px margin bottom-->
Heading
</h2>
<p class="mb-4"> <!--24px margin bottom-->
Body text here...
</div>
<!--Using fluid typography-->
# Display Heading
<p class="text-0">Body text scales smoothly...
<small class="text--1">Small print
Making Global Changes
Want Everything 10% Larger?
Change the grid unit:
/* In global.css */--grid-unit: 0.4125rem; /* 6.6px instead of 6px */
All spacing throughout the site scales proportionally!
Need Larger Body Text?
Update the base size:
// In tailwind.config.ts
"0": {
minSize: "1.0rem", // 16px mobile
maxSize: "1.125rem", // 18px desktop
lineHeight: "1.60"
}
The entire type scale adjusts while maintaining proportions!
Responsive Behavior
The system includes mobile-specific adjustments:
/* Mobile baseline (smaller screens) */
@media (max-width: 640px) {
:root {--baseline: 1.375rem; /* 22px */--grid-unit: 0.34375rem; /* 5.5px */
}
}
This creates tighter spacing on mobile while maintaining the mathematical relationships.
Component Integration
Every component uses these foundational values:
Headers
.header {
height: var(--space-12); /* 72px = 3 baselines */
padding: var(--space-3); /* 18px vertical */
}
Navigation
.nav-link {
font-size: 0.875rem; /* Slightly smaller than body */
padding: var(--space-2); /* 12px = 0.5 baseline */
}
Cards & Containers
.card {
padding: var(--space-4); /* 24px = 1 baseline */
margin-bottom: var(--space-6); /* 36px = 1.5 baselines */
}
Dark Mode Considerations
Typography needs special attention in dark mode:
/* Increased weight for better readability */
:root[data-theme="dark"] h1 {
font-weight: 450; /* vs 400 in light mode */
opacity: 0.95; /* Slight reduction to prevent glare */
}
/* Body text adjustments */
:root[data-theme="dark"] body {
font-weight: 425; /* Slightly heavier */
opacity: 0.90; /* Reduced brightness */
}
Performance Benefits
This systematic approach provides several performance advantages:
- CSS Variables: Changes cascade without recompilation
- Fluid Scaling: No JavaScript needed for responsive text
- Consistent Spacing: Fewer unique values = smaller CSS
- Mathematical Relationships: Predictable, maintainable system
Best Practices
- Always use the scale: Avoid arbitrary values like
mt-[37px]
- Respect the baseline: Vertical spacing should be multiples of 6px
- Let type flow: Use fluid units, not breakpoint-specific sizes
- Test at extremes: Check 320px and 1280px viewports
- Maintain proportions: If you adjust one value, consider the system
Debugging Tools
Add these classes to visualize the grid:
/* Show baseline grid */
.show-baseline {
background-image: repeating-linear-gradient(
to bottom,
rgba(0, 0, 255, 0.1) 0,
rgba(0, 0, 255, 0.1) 2px,
transparent 2px,
transparent var(--baseline)
);
}
/* Show 6px grid */
.show-grid {
background-image: repeating-linear-gradient(
to bottom,
rgba(255, 0, 0, 0.1) 0,
rgba(255, 0, 0, 0.1) 1px,
transparent 1px,
transparent var(--grid-unit)
);
}
Conclusion
A well-designed typography and spacing system is invisible to users but invaluable to developers. By building on mathematical relationships and single sources of truth, we’ve created a system that’s both beautiful and maintainable.
The key is restraint: two foundational decisions (base font size and grid unit) cascade through every element, creating harmony without rigidity. Whether you’re adjusting a single component or redesigning the entire site, the system scales with you.
Remember: Typography is the foundation of web design. When text looks good and spacing breathes properly, everything else falls into place.