Responsive Web Design: CSS Grid, Flexbox, and Media Queries
Responsive web design ensures your site looks good on every device — phone, tablet, laptop, and desktop. Since Google switched to mobile-first indexing, having a responsive design is no longer optional — it is a direct ranking factor. More than 60% of web traffic now comes from mobile devices, and users expect a seamless experience regardless of screen size.
This guide covers CSS Grid, Flexbox, media queries, and the mobile-first approach to building responsive layouts.
The Three Pillars of Responsive Design
- Fluid grids — layouts that use relative units (%, fr, vw) instead of fixed pixels
- Flexible images — images that scale within their containing elements
- Media queries — CSS rules that apply at specific viewport breakpoints
CSS Flexbox
Flexbox is designed for one-dimensional layouts — either a row or a column. It excels at distributing space and aligning items within a container.
.container {
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
---
.item {
flex: 1;
---Common Flexbox Patterns
.nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
---
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
---
.card {
flex: 1 1 300px;
---CSS Grid
CSS Grid is designed for two-dimensional layouts — rows and columns simultaneously. It is ideal for page-level layouts and complex grid systems.
.grid-container {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
gap: 1.5rem;
---Common Grid Patterns
.auto-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
---
.page-layout {
display: grid;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
---Fluid Typography
Fluid typography scales text smoothly between minimum and maximum sizes using clamp(). The formula clamp(minSize, preferredSize, maxSize) creates responsive text without breakpoints:
body {
font-size: clamp(1rem, 0.5rem + 2vw, 2rem);
---The preferred value can use viewport units, container query units, or custom properties. Fluid typography reduces the number of breakpoints needed and creates a smoother visual experience across all screen sizes.
Container Queries
Container queries (2023 baseline) allow components to respond to their container’s size rather than the viewport. Define a containment context with container-type: inline-size on the parent. Use @container (min-width: 400px) { ... } to style children based on container width. Container queries are a paradigm shift — components become truly reusable and context-independent.
Media Queries
Write base styles for mobile, then add breakpoints for larger screens:
.container {
display: flex;
flex-direction: column;
padding: 1rem;
---
@media (min-width: 768px) {
.container {
flex-direction: row;
flex-wrap: wrap;
}
---
@media (min-width: 1024px) {
.container {
max-width: 1200px;
margin: 0 auto;
}
---Responsive Images and Backgrounds
img {
max-width: 100%;
height: auto;
display: block;
---
.hero {
background-image: url('hero-mobile.jpg');
background-size: cover;
---
@media (min-width: 768px) {
.hero {
background-image: url('hero-tablet.jpg');
}
---Practical Layout
Combine all techniques for a complete responsive page:
.page {
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
---
@media (min-width: 768px) {
.card-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1.5rem;
}
---
@media (min-width: 1024px) {
.card-grid {
grid-template-columns: repeat(3, 1fr);
}
---Conclusion
Responsive design is not optional — it is table stakes for modern web development. Use CSS Grid for two-dimensional page layouts, Flexbox for one-dimensional component layouts, and media queries to adapt at breakpoints. Always start with mobile-first CSS, and test on real devices, not just browser resize.
FAQ
When should I use CSS Grid vs Flexbox? Use Grid for two-dimensional layouts (rows and columns simultaneously). Use Flexbox for one-dimensional layouts (a single row or column). Grid is for page-level layout; Flexbox is for component-level alignment.
What is the difference between auto-fit and auto-fill in Grid? auto-fit collapses empty tracks to zero width, allowing items to expand. auto-fill preserves empty track space, creating invisible columns. Use auto-fit when you want items to stretch, auto-fill when you want consistent column counts.
Do container queries replace media queries? No. Container queries respond to component size; media queries respond to viewport size. They are complementary. Use container queries for reusable components and media queries for page-level layout.
How do I test responsive designs on mobile? Use Chrome DevTools device toolbar for quick testing. Test on real devices for touch interactions, performance, and pixel density. Use BrowserStack or Sauce Labs for comprehensive device coverage.
Mobile-First vs Desktop-First
Responsive design starts with either mobile-first or desktop-first approach:
Mobile-first starts with styles for the smallest screen and adds complexity as the viewport grows using min-width media queries. This approach prioritizes performance (less CSS for mobile devices) and aligns with progressive enhancement. Mobile-first forces you to focus on core content before adding layout flourishes.
/* Base: mobile styles */
.layout { display: block; }
.nav { display: none; } /* Hidden on mobile, shown on desktop */
/* Tablet and up */
@media (min-width: 768px) {
.layout { display: grid; grid-template-columns: 200px 1fr; }
.nav { display: block; }
---Desktop-first starts with desktop layouts and uses max-width media queries to scale down. This is often faster for teams accustomed to desktop design but can lead to heavier CSS on mobile devices.
Performance Considerations
Responsive design impacts performance significantly. Mobile devices on cellular connections benefit from:
- Conditional loading — Load images appropriate to viewport size using
<picture>orsrcset - Touch targets — Minimum 44x44px tap targets per Apple/Google guidelines
- Reduce motion — Respect
prefers-reduced-motionfor users with vestibular disorders - Dark mode — Use
prefers-color-schemewith CSS custom properties for theme support - Print styles — Add
@media printrules to remove unnecessary elements and optimize for paper
Responsive Images
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 800px"
alt="Description"
loading="lazy"
decoding="async"
>The srcset and sizes attributes tell the browser which image to download based on viewport width and pixel density. The loading="lazy" attribute defers off-screen image loading, reducing initial page weight. This combination delivers appropriate image sizes for every device while conserving bandwidth.
Responsive Typography Systems
A systematic approach to responsive typography uses a modular scale. A modular scale uses a ratio (typically 1.25 or 1.333) to generate a sequence of font sizes:
:root {
--ratio: 1.25;
--text-sm: calc(1rem / var(--ratio));
--text-base: 1rem;
--text-lg: calc(1rem * var(--ratio));
--text-xl: calc(1rem * var(--ratio) * var(--ratio));
--text-2xl: calc(1rem * var(--ratio) * var(--ratio) * var(--ratio));
---Combine with clamp() for fluid scaling:
h1 { font-size: clamp(var(--text-2xl), 2.5vw + 1rem, var(--text-4xl)); }Responsive Tables
Tables are inherently non-responsive. Strategies include:
- Horizontal scroll — Wrap the table in a scrollable container. Simple but requires horizontal scrolling on mobile.
- Reorganized cards — Convert each table row into a card layout on small screens, using
display: gridwith labeled data cells. - Hidden columns — Hide less important columns on small screens and provide a toggle to show them.
For data tables (vs layout tables), the card pattern provides the best mobile experience. Use CSS to toggle between table and card layouts at breakpoints.
Responsive Design Testing Strategy
A comprehensive responsive testing strategy covers multiple dimensions:
Device coverage — Test on real devices spanning phone (320-428px), tablet (768-1024px), laptop (1280-1440px), and desktop (1920px+). Focus on the most common viewport widths for your audience (check analytics). Test both portrait and landscape orientations for mobile devices.
Content variability — Test with short and long content, single items and many items, no images and many images, active and empty states. Responsive layouts that work with one content length may break with another. Use test fixtures that vary content length to catch these issues.
Interaction methods — Test with mouse, touch, keyboard, and screen readers. Hover-based interactions fail on touch devices. Focus indicators must be visible for keyboard navigation. Touch targets must be at least 44x44px per WCAG guidelines. Responsive design must account for all input methods.
Performance Budgets
Set performance budgets for each viewport size. A 3-second time-to-interactive on desktop may take 10+ seconds on a 3G mobile connection. Use tools like Lighthouse and WebPageTest to measure performance across device profiles. Set budget thresholds: JavaScript bundle under 200KB, initial HTML under 50KB, time-to-interactive under 5 seconds on mobile.
Accessibility in Responsive Design
Responsive design and accessibility go hand in hand. Use relative units (em, rem, %) so layouts respond to user font size preferences. Ensure touch targets are at least 44x44px for mobile users. Support prefers-reduced-motion for users with vestibular disorders. Use prefers-color-scheme for dark mode support. Set the viewport meta tag correctly to prevent mobile browsers from scaling text.
Responsive Images and Media
Responsive images require multiple source variants. Use the <picture> element for art direction (cropping images differently at different sizes) and srcset for resolution switching. For video and iframes, use aspect-ratio containers to prevent layout shift during loading. Videos should use responsive player controls that adapt to screen size. Audio players need minimal controls on small screens — play/pause, volume, and progress are sufficient.
CSS Container Style Queries
Container style queries (emerging CSS feature) allow styling based on container styles rather than size. Combined with container size queries, they enable truly context-aware components. A card component could have different styling based on the parent container’s width and the current theme. This is the future of component-level responsive design, currently in early browser support.
Related: Check our Web Security guide.
For a comprehensive overview, read our article on Center A Div.