Responsive CSS Units — Complete Guide
In this tutorial, you will learn about Responsive CSS Units. We cover key concepts, practical examples, and best practices to help you master this topic.
Responsive CSS units like percentages, em, rem, vw, vh, vmin, vmax, ch, and the newer viewport-relative units enable flexible sizing that adapts to different screens, user preferences, and content contexts.
What You'll Learn
- Absolute vs relative units
- em and rem for typography and spacing
- Viewport units: vw, vh, vmin, vmax
- New CSS units: dvh, svh, lvh, dvw
- Unit comparison and when to use each
- Fluid typography with unit combinations
Why It Matters
- Choosing the right unit determines how content scales
- Wrong units cause overflow, unreadable text, or broken layouts
- Relative units respect user preferences and Accessibility
- Modern CSS units enable truly fluid designs
Real-World Use
- rem for consistent typography scaling
- vw for fluid hero section heights
- ch for readable line lengths
- dvh for mobile viewport heights that account for dynamic toolbars
flowchart LR A[CSS Units] --> B[Absolute] A --> C[Relative] B --> D[px, pt, cm] C --> E[Font-Relative] C --> F[Viewport-Relative] C --> G[Container-Relative] E --> H[em, rem, ch, ex] F --> I[vw, vh, vmin, vmax] G --> J[cqi, cqw]
Understanding CSS Units
CSS units fall into two categories: absolute and relative.
Absolute units (px, pt, cm, mm, in) have a fixed size. They do not scale with user preferences or viewport size.
Relative units scale based on something else — the font size, the viewport, or the container.
Font-Relative Units
em— Relative to the element's font sizerem— Relative to the root element's font sizech— Width of the "0" character in the current fontex— Height of the "x" character in the current font
Viewport-Relative Units
vw— 1 percent of viewport widthvh— 1 percent of viewport heightvmin— 1 percent of the smaller dimension (width or height)vmax— 1 percent of the larger dimension
New CSS Units (2024+)
dvh— Dynamic viewport height (accounts for browser chrome)svh— Small viewport height (minimum possible)lvh— Large viewport height (maximum possible)dvw— Dynamic viewport width
Code Example: When to Use Each Unit
/* px: fine details only */
html {
font-size: 16px; /* Base font size in px */
}
.border-thin {
border: 1px solid #ddd; /* Borders should be px */
}
.box-shadow {
box-shadow: 0 2px 4px rgba(0,0,0,0.1); /* Shadows in px */
}
/* rem: consistent spacing and sizing */
body {
font-size: 1rem; /* 16px default, respects user settings */
}
h1 { font-size: 2.5rem; } /* 40px */
h2 { font-size: 2rem; } /* 32px */
p { font-size: 1rem; } /* 16px */
.margin-section {
margin-top: 2rem; /* 32px */
}
.padding-card {
padding: 1.5rem; /* 24px */
}
/* em: component-relative sizing */
.card {
font-size: 1rem;
}
.card-title {
font-size: 1.25em; /* 20px if parent is 16px */
}
.card-body {
font-size: 0.875em; /* 14px if parent is 16px */
}
.card-padding {
padding: 1em; /* Scales with card font size */
}
/* vw: fluid typography (with clamp) */
h1 {
font-size: clamp(2rem, 5vw + 1rem, 4rem);
}
/* vh: full-height sections */
.hero {
height: 100vh; /* Full viewport height */
/* Mobile issue: 100vh includes browser chrome */
}
/* dvh: dynamic viewport height (mobile-friendly) */
.hero-mobile {
height: 100dvh; /* Adjusts when browser chrome appears/disappears */
}
/* ch: readable line lengths */
.article-content {
max-width: 65ch; /* Optimal line length for readability */
}
/* vmin: maintain aspect ratio */
.square {
width: 50vmin;
height: 50vmin; /* Always square, scales with smaller dimension */
}
Expected output: The layout uses appropriate units for each purpose. Text scales with user preferences. Hero sections adapt to dynamic mobile viewports. Line lengths are optimal for readability.
Code Example: Fluid Typography System
/* Complete fluid typography system */
:root {
/* Type scale with fluid sizes */
--text-xs: clamp(0.75rem, 0.7vw + 0.5rem, 0.875rem);
--text-sm: clamp(0.875rem, 1vw + 0.5rem, 1rem);
--text-base: clamp(1rem, 1.5vw + 0.5rem, 1.125rem);
--text-lg: clamp(1.125rem, 2vw + 0.5rem, 1.5rem);
--text-xl: clamp(1.25rem, 3vw + 0.5rem, 2rem);
--text-2xl: clamp(1.5rem, 4vw + 0.5rem, 2.5rem);
--text-3xl: clamp(2rem, 5vw + 1rem, 4rem);
/* Fluid spacing */
--space-xs: clamp(0.25rem, 0.5vw, 0.5rem);
--space-sm: clamp(0.5rem, 1vw, 1rem);
--space-md: clamp(1rem, 2vw, 1.5rem);
--space-lg: clamp(1.5rem, 3vw, 3rem);
--space-xl: clamp(2rem, 5vw, 5rem);
}
/* Usage */
body {
font-size: var(--text-base);
}
h1 { font-size: var(--text-3xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }
.section {
padding: var(--space-xl) var(--space-md);
}
.card {
padding: var(--space-md);
margin-bottom: var(--space-sm);
}
Expected output: All text sizes and spacing scale fluidly between viewport sizes without any media queries. The type scale maintains proportion across all screen sizes.
Common Mistakes
- Using px for font sizes — px does not respect user font size settings. Use rem for text.
- Using 100vh for hero sections — 100vh includes the browser chrome on mobile, causing the bottom of the hero to be hidden. Use 100dvh or min-height: 100vh.
- Using em for nested elements — em compounds with nesting (2em inside 2em = 4em). Use rem for global sizing, em for component-relative sizing.
- Ignoring the ch unit — The ch unit creates optimal line lengths (65-75ch) for readability.
- Using vw alone for typography — Pure vw units can make text too small on narrow screens or too large on wide screens. Always use clamp().
- Not setting a base font-size — The default 16px works but set it explicitly in your CSS reset.
- Using pt for digital design — pt is for print. Use px, rem, or em for digital.
Practice Questions
- What is the difference between em and rem? em is relative to the font size of the current element. rem is relative to the root element's font size.
- What does the ch unit measure? The width of the "0" (zero) character in the current font. It is used for optimal line lengths.
- Why is 100vh problematic on mobile browsers? Mobile browsers have dynamic toolbars (URL bar) that appear and disappear. 100vh includes the full viewport height, which can extend below the visible area.
- What is the difference between dvh, svh, and lvh? dvh (dynamic) adjusts when browser chrome appears/disappears. svh (small) is the minimum viewport height. lvh (large) is the maximum viewport height.
- Challenge: Create a complete fluid design system using only CSS custom properties and clamp(). Include at least 6 font sizes, 5 spacing values, and 3 border-radius values, all using clamp() with appropriate minimums and maximums.
FAQ
Mini Project
Rebuild a blog article page using only relative units (no px except for borders and shadows). Use: rem for all font sizes and spacing, ch for article content max-width, vw with clamp() for headings, dvh for hero section height, vmin for a decorative square element, em for component-relative padding on cards, and CSS custom properties for the fluid type scale. The page must include a header, article with headings and paragraphs, a sidebar with related links, and a footer. Test at multiple viewport sizes and with different browser font size settings.
What's Next
Continue with Lesson 8: Responsive Typography to learn how to make text readable on any screen size.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro