Loading
Learn mobile-first responsive design with media queries, flexbox, and CSS grid to build layouts that adapt to any screen size.
Most responsive design problems come from the same mistake: designing for desktop first, then trying to cram it into a phone. Flip that. Start with the smallest screen, then add complexity as space allows. This guide teaches you the patterns that actually work.
Mobile-first means your base CSS — without any media queries — targets small screens. Media queries then add layout rules for larger screens.
Why min-width instead of max-width? Because you are building up from the simplest layout. The mobile layout is the foundation. Every min-width query adds a layer of complexity that only activates when the screen can handle it.
Common breakpoints to memorize:
640px — large phones768px — tablets1024px — small laptops1280px — desktopsYou do not need all four. Most layouts only need two or three breakpoints.
Flexbox handles one-dimensional layouts — a row of buttons, a navigation bar, a card with an image and text side by side.
Here is a card component that places the image above text on mobile, beside it on larger screens:
Key flexbox properties to know:
flex-direction — row or columnjustify-content — spacing along the main axisalign-items — alignment on the cross axisflex-wrap: wrap — allow items to flow to the next linegap — spacing between items (cleaner than margins)Grid handles layouts where you care about rows and columns simultaneously — page layouts, dashboards, image galleries.
Grid shines for auto-filling content to whatever space is available:
That single rule creates a responsive grid with no media queries at all. Each card will be at least 280px wide. The browser figures out how many columns fit and distributes the remaining space evenly.
Text that looks good on a monitor becomes unreadable on a phone if you use fixed sizes. Use clamp() for fluid typography:
clamp(minimum, preferred, maximum) smoothly scales the value between your minimum and maximum based on viewport width. No breakpoints needed.
For spacing, use relative units:
Two more rules that prevent layout breakage on small screens:
The max-width: 100% rule prevents media from overflowing its container. box-sizing: border-box makes padding and borders count toward an element's declared width instead of adding to it.
Chrome DevTools device mode is a starting point, not a finish line.
Cmd+Shift+I or F12).Cmd+Shift+M).Things to check at every width:
Test on real devices when you can. Simulators miss things like how fat a thumb is compared to a cursor, how bright the sun makes screens outdoors, and how slow a 3G connection makes your page feel.
A quick responsive checklist before shipping:
Responsive design is not about making things look identical on every screen. It is about making every screen usable. A single-column layout on mobile is not a compromise — it is the correct design for that context.
[ ] No horizontal scroll at any width
[ ] Text is readable without zooming on 320px screens
[ ] All interactive elements are at least 48px tap targets
[ ] Images use max-width: 100% and height: auto
[ ] Layout uses mobile-first media queries (min-width)
[ ] Tested by dragging viewport, not just preset devices/* Base styles: mobile (no media query needed) */
.card-grid {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
padding: 1rem;
}
/* Tablet: 2 columns */
@media (min-width: 768px) {
.card-grid {
grid-template-columns: repeat(2, 1fr);
gap: 1.5rem;
padding: 2rem;
}
}
/* Desktop: 3 columns */
@media (min-width: 1024px) {
.card-grid {
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
}/* A navigation bar that stacks on mobile, sits in a row on desktop */
.navbar {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 1rem;
}
@media (min-width: 768px) {
.navbar {
flex-direction: row;
justify-content: space-between;
align-items: center;
}
}.feature-card {
display: flex;
flex-direction: column;
gap: 1rem;
}
.feature-card img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
border-radius: 8px;
}
@media (min-width: 768px) {
.feature-card {
flex-direction: row;
align-items: flex-start;
}
.feature-card img {
width: 300px;
flex-shrink: 0;
}
}/* A classic page layout: sidebar + main content */
.page-layout {
display: grid;
grid-template-columns: 1fr;
min-height: 100vh;
}
.sidebar {
padding: 1rem;
border-bottom: 1px solid #e5e7eb;
}
.main-content {
padding: 1rem;
}
@media (min-width: 1024px) {
.page-layout {
grid-template-columns: 280px 1fr;
}
.sidebar {
border-bottom: none;
border-right: 1px solid #e5e7eb;
}
}/* Cards that automatically fill available space */
.auto-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
}h1 {
font-size: clamp(1.75rem, 4vw, 3rem);
line-height: 1.2;
}
p {
font-size: clamp(1rem, 1.5vw, 1.125rem);
line-height: 1.8;
max-width: 65ch; /* Readable line length */
}.section {
padding: clamp(2rem, 5vw, 6rem) clamp(1rem, 3vw, 4rem);
}img,
video,
iframe {
max-width: 100%;
height: auto;
}
* {
box-sizing: border-box;
}