edubun 한국어

Responsive design with media queries

Without one meta tag, many phones lay a page out as if the screen were much wider (MDN gives 980 pixels as an example) and then shrink it, so a media query for phones never runs.

One page, every screen

Responsive design means building one page that adapts to whatever screen it lands on, from a narrow phone to a wide monitor, instead of making a separate mobile site. It rests on three ideas: a layout made of flexible widths instead of fixed ones, media that scale inside their containers, and media queries that adjust the layout at the points where it stops working. Flexbox and grid already do much of the work, as the last two units showed with wrapping cards and auto-fill columns.

The viewport meta tag

Many phones render pages in a virtual viewport wider than the screen, MDN gives 980 pixels as an example, and then shrink the result, because older sites were built for desktops. For a page that is designed to adapt, this gets in the way: a media query that should switch on below 600 pixels never runs, because the browser thinks the screen is 980 pixels wide. <meta name="viewport" content="width=device-width"> in the head tells the browser to use the real width of the device, measured in CSS pixels. Never add user-scalable=no or a low maximum-scale; MDN warns that blocking zoom shuts out people with low vision, and WCAG 1.4.4 expects text to be resizable to 200 percent.

Fluid widths and images

Fixed widths are the most common cause of sideways scrolling on phones. Prefer max-width to width: max-width: 70rem on a page wrapper lets it fill a small screen and stop growing on a large one. Images keep their natural pixel size by default, so a 1200 pixel photo spills out of a 390 pixel screen. img { max-width: 100%; height: auto; } lets images shrink to fit their container while keeping their proportions. WCAG 1.4.10, Reflow, asks that content work at a width of 320 CSS pixels without scrolling in two directions; checking your page in a 320 pixel wide window is a good habit.

Media queries

A media query wraps rules that apply only when a condition is true. @media (min-width: 600px) { ... } applies its rules when the viewport is at least 600 pixels wide. The usual approach is mobile first: write the base styles for a narrow screen, which are often the simplest (one column, everything stacked), and then add min-width queries that rearrange things as space grows. Choose breakpoints where your content starts to look wrong, not by guessing popular device sizes, since new screen sizes appear every year. Writing breakpoints in em, such as 40em, also makes them respond when a reader enlarges the text.

/* Base: one column for narrow screens */
.cols { display: grid; gap: 16px; }

/* From 600px: two columns */
@media (min-width: 600px) {
  .cols { grid-template-columns: 1fr 1fr; }
}

/* From 960px: a sidebar layout */
@media (min-width: 960px) {
  .cols { grid-template-columns: 240px 1fr 1fr; }
}
Mobile first: base styles, then min-width queries that add columns.
The same HTML at 390 and 1280 pixels: stacked on the phone, a sidebar and two columns on the wide screen.

Other things a query can ask

Media queries can test more than width. The reader preference features come from Media Queries Level 5: (prefers-color-scheme: dark) matches when the reader has chosen a dark theme in the operating system, so you can offer dark colours automatically. (prefers-reduced-motion: reduce) matches when the reader has asked for less motion, often because animation makes them dizzy; turn off large movements and parallax effects inside it. (hover: hover), from Level 4, tells you whether the main pointer can hover, which a touch screen cannot. print styles a page for paper, for example by hiding the menu. Finally, clamp() sizes things smoothly without a query: font-size: clamp(1.5rem, 4vw, 2.5rem) grows with the screen but never goes below 1.5rem or above 2.5rem.

The preview boxes on this page are only about 340 to 530 pixels wide, so the exercise below uses a small 300px breakpoint that you can see working. On a real site, choose breakpoints from your own content, such as 600px or 40em.
responsive designOne page that adapts to every screen
viewportThe visible area of the page in the browser
width=device-widthUse the real device width, not a virtual 980px
media query@media (condition) { rules }
mobile firstBase styles for narrow screens, then min-width queries
breakpointA width where the layout changes
prefers-reduced-motionThe reader asked for less animation
clamp()A value between a minimum and a maximum
  1. Why do phone media queries fail without the viewport meta tag?
    • The phone lays out the page at a wide virtual width
    • Phones ignore CSS
    • Media queries need JavaScript
  2. When does @media (min-width: 600px) apply?
    • When the viewport is 600px wide or wider
    • Below 600px
    • Only at exactly 600px
  3. What does mobile first mean?
    • Write base styles for narrow screens, then add min-width queries
    • Build the phone site first, the desktop site later
    • Hide content on phones
  4. Which rule stops large images from spilling out of narrow screens?
    • img { max-width: 100%; height: auto; }
    • img { width: 1200px; }
    • img { display: none; }
  5. At what width does WCAG 1.4.10 Reflow ask content to work without two-way scrolling?
  6. Why never set user-scalable=no?
    • It blocks zoom, shutting out people with low vision
    • It breaks media queries
    • It is not valid HTML
  7. How should you pick breakpoints?
    • Where your content starts to look wrong
    • From a list of popular phones
    • Always 768px
  8. Which query matches readers who asked for less animation?
    • (prefers-reduced-motion: reduce)
    • (hover: none)
    • (orientation: portrait)
  9. font-size: clamp(1.5rem, 4vw, 2.5rem) on a 1600px wide screen with 16px rem. What is the size?
  10. Why write breakpoints in em?
    • They respond when the reader enlarges the text
    • em is required in media queries
    • They load faster
Key points
  • Add the viewport meta tag; never block zoom.
  • Fluid widths, max-width instead of width, img { max-width: 100%; height: auto; }.
  • Mobile first with min-width queries at content breakpoints; also prefers-color-scheme, prefers-reduced-motion, print and clamp().