CSS Relative Units Best Practices
"We have text and that is sized in em and comes out at whatever size the display decides an em is. We can't code text in px (well maybe we could but I never see it done) so it's weird to use different measures in the same construction that can't even be converted into each other." - Andy
Why Relative Units Matter
Using relative units (em, rem) instead of absolute units (px) creates more accessible, scalable, and elegant designs. Here's why this approach is superior:
✅ Better Accessibility
- User font preferences respected: When users adjust their browser's base font size, everything scales proportionally
- Visual hierarchy maintained: Relationships between elements remain consistent at any scale
- Screen reader compatibility: Relative units work better with assistive technologies
✅ Responsive Design
- Proportional scaling: Everything scales together naturally across devices
- Fewer breakpoints needed: Elements adapt fluidly rather than requiring fixed adjustments
- Future-proof: Works well across different screen densities and zoom levels
✅ Design Consistency
- Unified measurement system: All elements use the same base unit (the user's preferred font size)
- Logical relationships: Spacing and sizing relate to text, which is the primary content
- Elegant proportions: Creates natural, harmonious layouts
✅ Development Benefits
- Easier maintenance: Change the base font size and everything scales accordingly
- More intuitive: Measurements relate to actual content rather than arbitrary pixel values
- Better team collaboration: Designers and developers think in the same proportional terms
- Design iteration flexibility: Easy to adjust spacing and proportions during design refinement - you can quickly compress or expand layouts by consistent percentages while maintaining visual relationships
Historical Context
The original vision of CSS included relative units as the primary measurement system. The shift to pixel-based design happened due to:
- Early browser inconsistencies (largely resolved in modern browsers)
- Designer habits from print design (where absolute measurements made sense)
- Framework defaults (many CSS frameworks defaulted to px measurements)
- Lack of understanding of the accessibility and scaling benefits
Implementation Guidelines
Base Font Size Strategy
Start with the browser default (typically 16px) and let users control their experience:
/* ✅ Good: Let browser/user control base size */
html {
/* Don't set font-size unless you have a specific reason */
}
/* ❌ Avoid: Overriding user preferences */
html {
font-size: 14px; /* Forces smaller text on users */
}
Unit Conversion Reference
Assuming 16px browser default:
Pixels | Em/Rem | Common Use |
---|---|---|
4px | 0.25em | Fine borders, small spacing |
8px | 0.5em | Small spacing |
12px | 0.75em | Small margins |
16px | 1em | Base font size, standard spacing |
20px | 1.25em | Medium spacing, border radius |
24px | 1.5em | Large spacing |
32px | 2em | Section spacing |
48px | 3em | Large section breaks |
Practical Examples
✅ Relative Units Version
.container {
max-width: 37.5em; /* 600px at 16px base */
padding: 1.25em 2.5em; /* 20px 40px */
border-radius: 1.25em; /* 20px */
margin: 2em auto; /* 32px auto */
}
.card {
padding: 1.25em; /* 20px */
margin-bottom: 1.5em; /* 24px */
border-radius: 0.5em; /* 8px */
}
@media (max-width: 48em) { /* 768px */
.container {
padding: 1em; /* 16px - scales with font */
}
}
❌ Pixel Version
.container {
max-width: 600px; /* Fixed size, ignores user preferences */
padding: 20px 40px; /* Fixed spacing */
border-radius: 20px; /* Fixed radius */
margin: 32px auto; /* Fixed margin */
}
.card {
padding: 20px; /* Fixed padding */
margin-bottom: 24px; /* Fixed margin */
border-radius: 8px; /* Fixed radius */
}
@media (max-width: 768px) { /* Fixed breakpoint */
.container {
padding: 16px; /* Arbitrary smaller size */
}
}
When to Use Each Unit
Use em
for:
- Component-level spacing: Padding, margins within components
- Border radius: Should scale with component size
- Component dimensions: Width/height that should relate to text size
Use rem
for:
- Layout-level spacing: Page margins, section gaps
- Consistent spacing systems: When you want spacing independent of parent font size
- Grid systems: Layout structures that should be consistent
Still use px
for:
- Thin borders: 1px borders (though
0.0625em
works too) - Box shadows: Sometimes absolute precision is needed
- Icon sizes: When matching specific icon dimensions
Real-World Example: DirectSponsor Auth Page
Here's how we converted the DirectSponsor authentication page from px to em:
Before (Pixels)
body {
padding: 32px 20px;
}
.container {
max-width: 600px;
border-radius: 20px;
padding: 20px 40px;
}
.actor-image {
max-width: 300px;
border-radius: 10px;
margin: 20px 0;
}
After (Relative)
body {
padding: 2em 1.25em; /* Scales with user's font preference */
}
.container {
max-width: 37.5em; /* Proportional to text */
border-radius: 1.25em; /* Scales with container */
padding: 1.25em 2.5em; /* Proportional spacing */
}
.actor-image {
max-width: 18.75em; /* Scales with content */
border-radius: 0.625em; /* Proportional radius */
margin: 1.25em 0; /* Consistent spacing */
}
Benefits Realized
When using relative units, you get:
- Automatic accessibility: Users with vision impairments who increase font size get properly scaled layouts
- Better responsive design: Elements maintain proportional relationships across screen sizes
- Unified design system: All measurements relate to the fundamental unit (text size)
- Future compatibility: Works well with new devices and screen technologies
- Elegant code: Measurements have logical relationships rather than arbitrary values
Migration Strategy
For existing projects:
- Start with new components: Use relative units for all new CSS
- Convert high-impact pages: Focus on frequently-used templates first
- Test at different scales: Verify layouts work at 150% and 200% zoom
- Update style guides: Document the relative unit system for your team
- Gradual conversion: Convert existing components as you work on them
Tools and Workflow
Quick Conversion
To convert px to em (assuming 16px base):
- Divide pixel value by 16
- 20px = 20/16 = 1.25em
- 8px = 8/16 = 0.5em
Browser Testing
Test your relative unit layouts: - Chrome: Settings → Appearance → Font size - Firefox: Preferences → General → Fonts and Colors → Advanced - Safari: Preferences → Advanced → Accessibility → Never use font sizes smaller than
Conclusion
Relative units represent the original, elegant vision of CSS: a measurement system that adapts to user needs while maintaining design integrity. By using em and rem instead of px, we create more accessible, maintainable, and future-proof designs.
The web is fundamentally about text and content. Our measurement systems should reflect that priority.