Skip to content

Responsive Design and Media Queries

beginner11 min read

Responsive Is Not About Screen Sizes

Let's get this straight: responsive design is not "desktop layout, tablet layout, mobile layout." It's about building interfaces that work at any width. The best responsive designs use zero or minimal media queries -- they flex, wrap, and scale using intrinsic sizing, flexbox, grid, and clamp(). Media queries are a precision tool for the cases fluid design can't handle, not your primary strategy.

Mental Model

Think of responsive design as water in containers. Water doesn't need instructions for each container shape — it naturally fills the space. Your layout should be water by default: flex, grid with auto-fit, clamp() for sizing. Media queries are like valves — you only add them when water alone can't achieve the right flow, like switching from a two-column to a single-column layout at a specific breakpoint.

Mobile-First: Why and How

Mobile-first means your base CSS (without any media queries) styles the mobile layout. Then you add min-width media queries to enhance for larger screens:

/* Base: mobile layout (no media query) */
.grid { display: grid; grid-template-columns: 1fr; gap: 1rem; }
.sidebar { display: none; }
.nav-items { display: none; }

/* Tablet and up */
@media (min-width: 768px) {
  .grid { grid-template-columns: 1fr 1fr; }
  .sidebar { display: block; }
}

/* Desktop and up */
@media (min-width: 1024px) {
  .grid { grid-template-columns: repeat(3, 1fr); }
}

Why mobile-first wins:

  1. Mobile styles are simpler — they're your base without complexity
  2. Mobile CSS loads faster — no unnecessary desktop styles
  3. Adding complexity (min-width) is cognitively easier than removing it (max-width)
  4. Progressive enhancement — baseline always works
Common Trap

Mixing min-width and max-width media queries creates confusion and overlap. Stick to min-width (mobile-first) exclusively. If you need "only between 768px and 1024px," use a range: @media (min-width: 768px) and (max-width: 1023px) — or better, the modern range syntax: @media (768px <= width < 1024px).

Choosing Breakpoints: Content, Not Devices

This is a mindset shift. Don't pick breakpoints based on iPhone/iPad/desktop widths. Pick them based on where your layout breaks:

/* Bad: Device-centric breakpoints */
@media (min-width: 375px) { }  /* iPhone */
@media (min-width: 768px) { }  /* iPad */
@media (min-width: 1024px) { } /* Desktop */

/* Good: Content-centric breakpoints */
/* "Where does the sidebar start feeling cramped?" → that's the breakpoint */

Common content-centric breakpoints (as a starting point, not dogma):

/* Compact: single column */
/* @media (min-width: 640px) — Two columns become viable */
/* @media (min-width: 1024px) — Three columns + sidebar viable */
/* @media (min-width: 1280px) — Full desktop layout */

Fluid Design: Fewer Breakpoints, More Math

clamp() for Fluid Sizing

h1 {
  /* Min: 1.5rem, Preferred: 4vw + 0.5rem, Max: 3rem */
  font-size: clamp(1.5rem, 4vw + 0.5rem, 3rem);
}

.container {
  /* Fluid padding */
  padding: clamp(1rem, 3vw, 4rem);

  /* Fluid width with maximum */
  width: clamp(320px, 90%, 1200px);
}

.gap {
  /* Fluid gap */
  gap: clamp(0.5rem, 2vw, 2rem);
}

Intrinsic Responsive Layouts

/* Grid that responds without any media queries */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: clamp(1rem, 2vw, 2rem);
}

/* Flexbox that wraps naturally */
.features {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
}
.feature {
  flex: 1 1 300px; /* Min 300px, grows to fill */
}

When Media Queries Are Still Necessary

So if fluid design is so great, when do you still need media queries? Turns out, some layout changes can't be fluid:

/* Navigation: hamburger on mobile, horizontal on desktop */
@media (min-width: 768px) {
  .nav { flex-direction: row; }
  .hamburger { display: none; }
}

/* Sidebar: hidden on mobile, visible on desktop */
@media (min-width: 1024px) {
  .layout { grid-template-columns: 280px 1fr; }
  .sidebar { display: block; }
}

/* Content reordering */
@media (min-width: 768px) {
  .hero-text { order: -1; } /* Text before image on desktop */
}

Modern Media Query Features

Beyond width, media queries can detect a lot more than you might expect.

/* Range syntax (modern) */
@media (768px <= width < 1024px) { }

/* Hover capability */
@media (hover: hover) {
  .card:hover { transform: translateY(-4px); }
}

/* Reduced motion preference */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; }
}

/* Dark mode preference */
@media (prefers-color-scheme: dark) {
  :root { --bg: #0f0f1a; --text: #e5e7eb; }
}

/* High contrast */
@media (prefers-contrast: more) {
  :root { --border-color: #000; }
}
Execution Trace
Base styles
Mobile layout: single column, minimal padding
No media queries — this is the foundation
Fluid values
clamp() for font-size, padding, gap
Scales smoothly between mobile and desktop
auto-fit grid
Cards wrap from 1 to 4 columns automatically
No media queries needed for card grid
min-width: 768px
Add sidebar, switch to horizontal nav
Binary layout change — can't be fluid
min-width: 1024px
Three-column layout, wider sidebar
Full desktop layout activated

Production Scenario: Responsive Dashboard

.dashboard {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(1rem, 2vw, 2rem);
  padding: clamp(1rem, 3vw, 3rem);
}

/* Stats cards: responsive without media queries */
.stat-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  gap: 1rem;
}

/* Chart area + sidebar: needs a media query for the layout shift */
@media (min-width: 1024px) {
  .dashboard {
    grid-template-columns: 1fr 300px;
  }
}

/* Data table: horizontal scroll on mobile, full width on desktop */
.table-wrapper {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
What developers doWhat they should do
Writing desktop-first CSS and using max-width queries to adjust for mobile
Mobile-first ensures the simplest styles load first and larger-screen complexity is layered on
Write mobile-first CSS and use min-width queries to enhance for larger screens
Using device-specific breakpoints (375px for iPhone, 768px for iPad)
Device dimensions change constantly. Your content's needs are the reliable guide.
Choose breakpoints based on where YOUR layout actually breaks
Using media queries for every responsive behavior
Fluid design produces fewer breakpoints, smoother transitions, and less CSS to maintain
Use fluid values (clamp, minmax, flex-wrap, auto-fit) first, media queries only for binary layout changes
Forgetting the viewport meta tag
Without it, mobile browsers render at desktop width and scale down, making all responsive CSS useless
Always include `<meta name='viewport' content='width=device-width, initial-scale=1'>`
Quiz
Why is min-width preferred over max-width for media queries?
Quiz
A card grid uses repeat(auto-fit, minmax(300px, 1fr)) and the container is 280px wide. What happens?
Key Rules
  1. 1Mobile-first: base CSS is mobile, min-width media queries add complexity for larger screens
  2. 2Choose breakpoints based on content, not device dimensions
  3. 3Use fluid values (clamp, auto-fit, flex-wrap) before reaching for media queries
  4. 4Media queries are for binary layout changes that can't be fluid — not for tweaking sizes
  5. 5Always include the viewport meta tag for responsive CSS to work on mobile