Responsive Design
Responsive design makes a single layout work across phones, tablets, and large desktops — adapting to whatever screen, orientation, and input the user brings. With users split across every device size, it's the default expectation, not a feature.
The modern toolkit makes it easier than ever: a mobile-first baseline, fluid units like clamp(), intrinsic Grid layouts, and container queries that respond to a component's own width rather than the viewport's.
TL;DR
- Design mobile-first: base styles for small screens, enhance upward.
- Use fluid units (
%,rem,clamp()) over fixed pixels. - Use Grid for page layout, Flexbox for component layout.
- Reach for container queries to make components self-responsive.
- Test on real devices, and size touch targets for fingers (≥44px).
Quick Example
A grid that goes 1 → 2 → 3 columns as the screen grows, plus fluid headings — minimal media queries:
Core Concepts
Mobile-first
Write base styles for the smallest screen, then layer complexity with min-width media queries. Phones get the lightest CSS, and you enhance progressively.
Responsive units
rem/em (relative to font size), % (relative to parent), vw/vh (viewport), and clamp(min, preferred, max) for fluid sizing with guardrails.
Container queries
Style a component by its own container's width (@container), so a card looks right whether it's in a sidebar or a full-width row — true component-level responsiveness. See CSS Fundamentals.
Best Practices
- Start mobile-first; it yields smaller CSS and forces content priority.
- Prefer fluid type/spacing (
clamp()) over a ladder of fixed breakpoints. - Make touch targets at least ~44×44px and keep tap areas clear of each other.
- Test on actual devices and with browser device emulation, not just by dragging the window.
Common Mistakes
Desktop-first with max-width
Fixed pixel widths that don't adapt
FAQ
Why mobile-first instead of desktop-first?
Mobile-first means your base styles target the most constrained device, then you add complexity for larger screens with min-width queries. It produces smaller CSS, avoids overrides piling up, and forces you to prioritize core content.
How many breakpoints do I need?
Fewer than you'd think. Let content decide — add a breakpoint where the layout actually breaks, not at arbitrary device sizes. Fluid units (clamp(), auto-fit grids) reduce how many you need at all.
Container queries or media queries?
Media queries respond to the viewport; container queries respond to a component's parent width. Use container queries for reusable components that appear in different-sized contexts, and media queries for overall page structure.
Should I use px, rem, or viewport units?
Use rem for type and spacing so it scales with user preferences, %/fr for layout, and viewport units (often inside clamp()) for fluid sizing. Avoid fixed px widths that can't shrink.
Related Topics
- CSS Fundamentals — Grid, Flexbox, and fluid units
- Tailwind CSS — Responsive variants out of the box
- Web Performance — Mobile performance
- Accessibility — Reflow and zoom support