AniUI Academy

Responsive Design and Media Queries

What "responsive" means as a design goal, @media query syntax, min-width versus max-width breakpoints, and why the viewport meta tag must be present for any of it to work on a phone.

9 min read

Most visitors to a page you build won't be on your laptop, at your browser window's exact width. They'll be on a phone in portrait, a tablet, a folded laptop lid's worth of window, or a 32-inch monitor with the browser snapped to half the screen. Responsive design is the practice of building one page that keeps working — readable, usable, not broken — across that entire range, rather than building separate pages for separate devices.

"Working" doesn't mean identical at every width. A three-column layout that's comfortable at 1400px is usually the wrong shape for a 375px phone screen. The goal is that at every width, something appropriate is showing, and the transition between them is deliberate rather than accidental.

The tool: @media queries

A media query is a conditional block of CSS: apply these rules only when a condition about the viewport is true.

p {
  font-size: 16px;
}
 
@media (min-width: 768px) {
  p {
    font-size: 18px;
  }
}

Read that as: paragraphs are 16px normally, but once the viewport is at least 768px wide, bump them to 18px. The rules inside @media are ordinary CSS — same selectors, same declarations — just gated behind a condition. Everything you already know about the cascade still applies inside the block: a more specific selector still wins, and a rule declared later still overrides an earlier one of equal specificity.

min-width versus max-width

Both describe a threshold, but they point in opposite directions:

/* Applies at 768px and wider */
@media (min-width: 768px) {
  .layout { display: flex; }
}
 
/* Applies at 768px and narrower */
@media (max-width: 768px) {
  .layout { display: block; }
}
  • min-width: 768px is a floor — "at least this wide." The rules apply from 768px upward, with no upper limit.
  • max-width: 768px is a ceiling — "at most this wide." The rules apply from 768px downward, with no lower limit.

It's easy to reach for these interchangeably and get confused about which direction a rule "kicks in." A trick that helps: read min-width as "once the screen is at least this big" and max-width as "as long as the screen is no bigger than this." The next lesson goes deep on which one to build your whole CSS around — this one is just about the syntax.

Combining conditions with and

You can require more than one condition at once by chaining them with and:

@media (min-width: 600px) and (max-width: 900px) {
  /* Applies only in this specific width band, e.g. a tablet-ish size */
  .sidebar { display: none; }
}

This is genuinely useful for "only in this middle range" rules — hiding a sidebar just in the awkward zone where there's room for it but not enough room to make it useful, for example. You can chain as many and conditions as you need; each one narrows the range the query matches.

Choosing breakpoints from your content, not from devices

The tempting approach when you first meet media queries is to look up "iPhone width" and "iPad width" and write breakpoints that match them exactly. Don't. Device screen sizes are not a fixed, stable list — new phones, tablets and laptops ship constantly, at new widths, and a breakpoint tied to "the current iPhone" is wrong the day a differently-sized iPhone ships. There is no such thing as a definitive list of device widths to design for.

The well-established alternative: resize your own browser window and watch your actual content. Shrink it slowly until something looks wrong — text lines that are too long to read comfortably, a navigation bar that starts wrapping awkwardly, columns that get too narrow to hold their content. That width, wherever it happens to land — 640px, 715px, 860px, whatever number your specific layout breaks at — is your breakpoint. It's derived from the design itself, not from a device catalog, so it stays correct regardless of what hardware ships next year.

/* Not "this is where tablets are" — this is "this is where our
   three-column layout gets cramped and needs to drop to two" */
@media (max-width: 860px) {
  .card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

You'll usually end up with two to four breakpoints for a typical page, not a dozen — one for each point where the layout genuinely needs to reshape, not one for every device you can think of.

Why the viewport meta tag has to be there

You met this line already, back in the document-structure lesson:

<meta name="viewport" content="width=device-width, initial-scale=1" />

It's worth revisiting now that it actually matters for what you're doing. Here's the concrete failure mode without it: mobile browsers historically assumed pages were built for a desktop-width screen, roughly 980px wide. A phone with no viewport meta tag renders the page at that assumed 980px-wide layout, then zooms the entire rendered page out to fit the phone's physical screen — text and all. Visually, everything looks tiny and the user has to pinch-zoom to read it.

This breaks media queries in a very specific way: @media (max-width: 600px) asks "is the viewport 600px or narrower?" But without the meta tag, the browser is reporting that virtual 980px-wide layout as the viewport width, regardless of the phone's actual, physical screen size. A query written for "is this a narrow phone screen" never matches, because the browser never reports a narrow width — it's always reporting that same wide virtual viewport, just zoomed out visually.

width=device-width tells the browser: "use the device's real, physical pixel width as the layout width, don't assume 980px." initial-scale=1 says "start at 100% zoom, don't zoom out to compensate." With both set, a min-width/max-width query lines up with the actual width the user is looking at — which is the entire point of writing one.

Try it yourself

This page includes the viewport meta tag and a media query that switches the card layout from a single column to two columns once the viewport is at least 700px wide. The embed below has a fixed width, so resizing it isn't possible here — but you can copy this into a real file, open it in a browser, and resize the window to watch the breakpoint trigger live.

Try it yourself
Loading playground...

What to remember

  • Responsive design means one page that stays usable across a wide range of viewport widths, not a separate page per device.
  • @media (condition) { ... } gates ordinary CSS rules behind a viewport condition — everything inside still follows the normal cascade.
  • min-width is a floor (applies at that width and wider); max-width is a ceiling (applies at that width and narrower).
  • Combine conditions with and to match a specific width band.
  • Choose breakpoints by resizing your own browser and watching where your content breaks, not by targeting named devices — device sizes change constantly, your content's breaking points don't.
  • The viewport meta tag (width=device-width, initial-scale=1) is a prerequisite for media queries to mean anything on a real phone — without it, the browser measures a virtual desktop-width viewport instead of the phone's actual width.

Check yourself

3 questions · pass 3/3 to unlock Responsive Images

up to 50
  1. 1.What does @media (min-width: 768px) { ... } mean?

  2. 2.A page has no viewport meta tag. What actually happens on a real phone?

  3. 3.Why is "pick breakpoints where your content starts to look bad" a better strategy than "pick breakpoints matching named devices"?

3 left to answer