Responsive units are CSS units that scale relative to their context rather than having fixed values. Using rem, em, percentages, and viewport units instead of pixels makes your designs more flexible, accessible, and easier to maintain. These relative units automatically adapt to user preferences, parent elements, and viewport sizes, creating truly responsive layouts without complex calculations.
Absolute vs Relative Units
CSS units fall into two categories: absolute units (fixed size) and relative units (scale based on context).
Absolute Units
- px (pixels): Fixed size, doesn't scale
- pt (points): Print-based, 1pt = 1/72 inch
- cm, mm, in: Physical measurements
- Same size regardless of context
- Less flexible for responsive design
- Can ignore user accessibility settings
Relative Units (Recommended)
- rem: Relative to root font-size
- em: Relative to parent font-size
- %: Relative to parent element
- vw, vh: Relative to viewport
- Scales automatically with context
- Better for responsive design
- Respects user preferences
Why Relative Units Matter: Users can adjust their browser's default font size for accessibility. Relative units respect these settings, while pixels ignore them. This makes relative units essential for accessible, user-friendly websites.
rem Units
rem (root em) is relative to the root element's (<html>) font size. It's the most popular unit for modern responsive design.
/* Default root font-size is 16px in most browsers */
html {
font-size: 16px; /* 1rem = 16px */
}
/* Using rem for consistent scaling */
.heading {
font-size: 2rem; /* 32px (16px × 2) */
margin-bottom: 1rem; /* 16px (16px × 1) */
}
.text {
font-size: 1rem; /* 16px (16px × 1) */
padding: 0.5rem; /* 8px (16px × 0.5) */
}
.small {
font-size: 0.875rem; /* 14px (16px × 0.875) */
}
/* If user changes root to 20px, everything scales */
html {
font-size: 20px; /* 1rem = 20px now */
}
/* Now .heading is 40px, .text is 20px, .small is 17.5px */
/* Common pattern: Use % for easier calculations */
html {
font-size: 62.5%; /* 62.5% of 16px = 10px */
}
/* Now 1rem = 10px, 1.6rem = 16px, 2.4rem = 24px */rem Units Example
✨ rem Best Practices:
Use rem for font sizes, padding, margin, and most spacing. This creates a consistent scale across your entire site that respects user preferences. Set font-size: 62.5% on html to make 1rem = 10px for easier mental math.
em Units
em is relative to the parent element's font size. It can compound when nested, which can be both powerful and tricky.
/* em is relative to parent font-size */
.parent {
font-size: 16px;
}
.child {
font-size: 1.5em; /* 24px (16px × 1.5) */
padding: 0.5em; /* 12px (24px × 0.5) - uses own font-size */
margin-bottom: 1em; /* 24px (24px × 1) */
}
/* Compounding problem with nested em */
.level-1 {
font-size: 1.2em; /* 19.2px if parent is 16px */
}
.level-1 .level-2 {
font-size: 1.2em; /* 23.04px (19.2px × 1.2) - COMPOUNDS! */
}
.level-1 .level-2 .level-3 {
font-size: 1.2em; /* 27.65px (23.04px × 1.2) - COMPOUNDS AGAIN! */
}
/* When to use em: component-specific spacing */
.button {
font-size: 16px;
padding: 0.5em 1em; /* Scales with button font-size */
border-radius: 0.25em;
}
.button-large {
font-size: 20px;
/* Padding automatically becomes 10px 20px */
}em Units Example (Shows Compounding)
Watch Out for Compounding: When using em for font sizes in nested elements, values compound (multiply). Use rem for font sizes to avoid this. Use em for padding/margin when you want spacing to scale with the element's font size.
Percentage Units (%)
Percentages are relative to the parent element's corresponding property. They're essential for fluid layouts.
/* Percentage is relative to parent */
.parent {
width: 800px;
font-size: 16px;
}
.child {
width: 50%; /* 400px (50% of 800px) */
font-size: 125%; /* 20px (125% of 16px) */
padding: 5%; /* 40px (5% of parent width) */
}
/* Common pattern: Fluid containers */
.container {
width: 90%; /* 90% of parent/viewport width */
max-width: 1200px; /* But never wider than 1200px */
margin: 0 auto; /* Center it */
}
/* Percentage height requires parent height */
.parent {
height: 500px; /* Must have explicit height */
}
.child {
height: 50%; /* 250px (50% of 500px) */
}
/* Without parent height, % height doesn't work */
.no-height-parent {
/* No height set */
}
.child {
height: 50%; /* Won't work! */
}Percentage Units Example
Viewport Units (vw, vh, vmin, vmax)
Viewport units are relative to the browser's viewport size. They're perfect for full-screen sections and responsive typography.
/* Viewport units */
.element {
width: 100vw; /* 100% of viewport width */
height: 100vh; /* 100% of viewport height */
font-size: 5vw; /* 5% of viewport width */
}
/* vmin and vmax */
.element {
width: 50vmin; /* 50% of smaller dimension (width or height) */
height: 50vmax; /* 50% of larger dimension */
}
/* Common patterns */
/* Full viewport hero */
.hero {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
/* Responsive typography */
.heading {
font-size: calc(2rem + 2vw); /* Scales with viewport */
/* Min 2rem, grows with viewport */
}
/* Full-width section */
.full-width {
width: 100vw;
margin-left: calc(-50vw + 50%); /* Break out of container */
}
/* Viewport units with min/max */
.text {
font-size: clamp(1rem, 2vw, 3rem);
/* Min 1rem, ideal 2vw, max 3rem */
}Viewport Units
| Property | Values | Description |
|---|---|---|
vw | 1vw = 1% of viewport width | Scales with browser width |
vh | 1vh = 1% of viewport height | Scales with browser height |
vmin | 1vmin = 1% of smaller dimension | Min of vw or vh |
vmax | 1vmax = 1% of larger dimension | Max of vw or vh |
Viewport Units Example (Resize Browser)
📱 Viewport Unit Gotchas:
100vh on mobile can include/exclude the address bar depending on browser, causing layout shifts. Use 100dvh (dynamic viewport height) in modern browsers, or combine with JavaScript for precise control. Viewport units for font sizes can get too small/large on extreme screens—use clamp() to set boundaries.
Unit Comparison and Use Cases
When to Use Each Unit
| Property | Values | Description |
|---|---|---|
px | Fixed pixels | Use for: borders, shadows, fine details |
rem | Root font-size | Use for: font sizes, padding, margin, spacing (MOST COMMON) |
em | Parent font-size | Use for: component padding that scales with font-size |
% | Parent element | Use for: widths, fluid layouts, columns |
vw/vh | Viewport size | Use for: full-screen sections, hero areas |
vmin/vmax | Viewport dimension | Use for: maintaining aspect ratios |
Recommended Unit Strategy
/* Recommended approach for most projects */
/* 1. Set root font-size */
html {
font-size: 62.5%; /* 1rem = 10px */
}
/* 2. Use rem for most spacing and typography */
body {
font-size: 1.6rem; /* 16px */
line-height: 1.5;
padding: 2rem; /* 20px */
}
h1 {
font-size: 3.2rem; /* 32px */
margin-bottom: 2rem; /* 20px */
}
.container {
max-width: 120rem; /* 1200px */
margin: 0 auto;
padding: 3rem; /* 30px */
}
/* 3. Use % for widths and fluid layouts */
.column {
width: 50%;
padding: 2rem;
}
/* 4. Use px for small, precise values */
.button {
border: 1px solid #ddd;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
/* 5. Use viewport units for full-screen sections */
.hero {
min-height: 100vh;
padding: 5vw;
}
/* 6. Use em for component-specific spacing */
.button {
font-size: 1.6rem;
padding: 0.5em 1em; /* Scales with button font-size */
border-radius: 0.25em;
}
/* 7. Combine units with calc() and clamp() */
.heading {
font-size: clamp(2rem, 5vw, 5rem);
/* Min 2rem, ideal 5vw, max 5rem */
}
.section {
padding: calc(2rem + 2vw);
/* Base 2rem + scales with viewport */
}Recommended Unit Strategy
Practical Responsive Examples
Responsive Typography
Responsive Typography with clamp()
Fluid Container
Fluid Container with Multiple Units
Responsive Card Grid
Responsive Card Grid with Mixed Units
Key Takeaways
- rem: Relative to root font-size (RECOMMENDED for most spacing)
- em: Relative to parent font-size (use for component padding)
- %: Relative to parent element (use for widths)
- vw/vh: Viewport width/height (use for full-screen sections)
- vmin/vmax: Smaller/larger viewport dimension
- Set
font-size: 62.5%on html for easier rem calculations - Use rem for font-sizes to respect user preferences
- Use em for component spacing that scales with font-size
- Use % for fluid widths and columns
- Use
clamp()to set min/max boundaries for viewport units - Combine units with calc() for complex calculations
- Use px only for borders, shadows, and fine details
What's Next?
Now that you understand responsive units and how to use them effectively, you're ready to learn about Container Queries. In the next lesson, we'll explore modern container-based responsive design that lets components adapt based on their container size rather than viewport size—a powerful new tool for component-based design.
Responsive units are fundamental to creating flexible, accessible websites. Practice using rem, percentages, and viewport units together, and you'll build layouts that adapt beautifully to any screen size while respecting user preferences!