—CSS Series · Post 09: Responsive Design
Responsive Design
Built for Every Screen
Over half of all web traffic comes from mobile. If your layout only works on a desktop, it's only working half the time. This post teaches you how to build for all screen sizes from the start.
💬 "It Looks Perfect on My Laptop…"
You resize the browser on mobile and your three-column card grid becomes a horizontal mess of overlapping text. The sidebar is nowhere to be found. The heading is 48px on a 320px screen. Everything looks wrong.
Responsive design is not a separate step you add at the end. It's a mindset you build in from the beginning. And the good news: you already know most of the tools. Media queries are how you apply them at the right screen size.
🧠 The Viewport Meta Tag — Non-Negotiable
Before media queries work correctly, you need this line in your <head>. Without it, mobile browsers zoom out and display a scaled-down desktop view, ignoring your responsive CSS entirely.
<head>
<!-- This line must be in every HTML file you build -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
/* width=device-width: use the device's actual screen width
initial-scale=1.0: don't zoom in or out on load
Without this: mobile browsers fake a ~980px viewport and shrink everything */🧱 Media Queries
A media query is a conditional CSS block. It says: apply these styles only when this condition is true. The most common condition is viewport width.
/* Basic syntax */
@media (max-width: 768px) {
/* These styles only apply when screen is 768px or narrower */
.card-grid {
grid-template-columns: 1fr; /* one column on mobile */
}
}
/* min-width — styles apply when screen is this wide or WIDER */
@media (min-width: 768px) {
.card-grid {
grid-template-columns: repeat(3, 1fr);
}
}
/* Range — between two widths */
@media (min-width: 640px) and (max-width: 1024px) {
/* Tablet only */
}Common Breakpoints
The common breakpoints (640px, 768px, 1024px) are suggestions based on common device sizes, not universal laws. The real rule: add a breakpoint where your design breaks, not at an arbitrary width. Resize the browser slowly and add media queries wherever things start looking wrong.
Mobile-First vs Desktop-First
Mobile-first means writing your base CSS for mobile screens, then using min-width media queries to add styles as the screen gets wider. This is the modern professional approach.
Desktop-first means writing for large screens first, then using max-width queries to subtract or override styles as the screen gets narrower. This is how older codebases were often written.
/* ─── MOBILE FIRST ─── */
/* Base styles: single column, simple layout */
.card-grid {
display: grid;
grid-template-columns: 1fr; /* one column */
gap: 16px;
}
.navbar {
flex-direction: column;
gap: 12px;
}
/* Tablet and up — add columns */
@media (min-width: 640px) {
.card-grid {
grid-template-columns: repeat(2, 1fr);
}
.navbar {
flex-direction: row;
justify-content: space-between;
}
}
/* Desktop and up — three columns */
@media (min-width: 1024px) {
.card-grid {
grid-template-columns: repeat(3, 1fr);
}
}Mobile-first produces cleaner, smaller CSS because simple single-column layouts need fewer rules. You're adding complexity as space allows, rather than removing it under constraints. It also forces you to prioritize content — what's essential when space is limited? Everything else is an enhancement.
Fluid Sizing — max-width and min-width
/* Fluid container — fills up to a max, then stops */
.container {
width: 100%; /* full width on small screens */
max-width: 860px; /* stops growing at 860px */
margin: 0 auto; /* centered */
padding: 0 24px; /* side breathing room */
}
/* Fluid font sizing with clamp() */
h1 {
font-size: clamp(28px, 5vw, 52px);
/* minimum: 28px, ideal: 5% of viewport width, max: 52px
scales smoothly between breakpoints — no jumps */
}
/* Images always fluid */
img {
width: 100%;
height: auto;
display: block;
}Common Responsive Patterns
/* ─── Hide on mobile, show on desktop ─── */
.desktop-only { display: none; }
@media (min-width: 768px) {
.desktop-only { display: block; }
}
/* ─── Hide on desktop, show on mobile ─── */
.mobile-only { display: block; }
@media (min-width: 768px) {
.mobile-only { display: none; }
}
/* ─── Stack on mobile, side-by-side on desktop ─── */
.layout {
display: flex;
flex-direction: column; /* stacked by default */
gap: 24px;
}
@media (min-width: 768px) {
.layout { flex-direction: row; } /* side by side */
}
/* ─── Responsive typography ─── */
body { font-size: 16px; }
@media (min-width: 768px) {
body { font-size: 17px; }
}Chrome and Firefox DevTools have a responsive design mode (F12 → the phone/tablet icon). You can test any screen size without needing a real device. Check your layout at 320px (smallest common mobile), 375px (iPhone), 768px (tablet), and 1280px (typical desktop). If something breaks, that's where your media query goes.
Mini Build: Responsive Landing Page
Take the card grid you built in the Flexbox post and make it fully responsive — mobile-first, two breakpoints, fluid typography.
Add the viewport meta tag if it's not already there. Then write your base (mobile) CSS first — one column, full width, readable font sizes.
* { margin: 0; padding: 0; box-sizing: border-box; }
html { font-size: 16px; }
body {
background: #0a0a0f;
color: #e0e0e8;
font-family: sans-serif;
padding: 24px; /* tight padding on mobile */
}
.hero-title {
font-size: clamp(28px, 7vw, 52px); /* fluid — no jumps */
margin-bottom: 1rem;
}
.card-grid {
display: grid;
grid-template-columns: 1fr; /* mobile: one column */
gap: 16px;
margin-top: 2rem;
}
.navbar {
display: flex;
flex-direction: column; /* mobile: stacked */
gap: 12px;
margin-bottom: 2rem;
}Add the tablet breakpoint — two columns, horizontal navbar.
@media (min-width: 640px) {
body { padding: 32px; }
.card-grid {
grid-template-columns: repeat(2, 1fr); /* two columns */
gap: 20px;
}
.navbar {
flex-direction: row;
justify-content: space-between;
align-items: center;
}
}Add the desktop breakpoint — three columns, wider padding.
@media (min-width: 1024px) {
body { padding: 48px; }
.card-grid {
grid-template-columns: repeat(3, 1fr); /* three columns */
gap: 24px;
}
}Test in DevTools. Open the responsive design panel, drag the width from 320px to 1440px, and watch your layout shift at exactly 640px and 1024px. If anything looks wrong at any size, that's where you add your next fix.
💛 Your Sites Work Everywhere Now
Responsive design isn't about making things "work on mobile." It's about building for the full range of human screen sizes — from 320px pocket computers to 2560px monitors — without making assumptions about where your reader is.
- The viewport meta tag is mandatory — it turns on responsive behavior
- Media queries apply CSS conditionally based on screen width
- Mobile-first means base styles for small, then min-width adds for larger
- max-width: 860px + margin: 0 auto creates a centered, fluid container
- clamp() creates fluid typography that scales smoothly between sizes
- Always test in DevTools at multiple widths — don't assume it looks right
You now have the full foundational toolset: structure, typography, colors, layout, positioning, Flexbox, Grid, and responsiveness. The series continues with specificity, transitions, CSS variables, and professional architecture.
I built my first portfolio entirely on a 1440px monitor. It looked great. Clean. I was proud of it. Then I opened it on my phone to show someone and the text was the size of an ant and the three-column layout was a horizontal scroll nightmare.
The viewport meta tag was missing. That was it. One line. The entire site was rendering at fake desktop width and scaling down. I felt like I'd been betrayed by my own code.
Now the viewport meta tag is the first thing I put in every HTML file. Before the title. Before the stylesheet link. First line in the head, every single time. Consider this your reminder to do the same.