Responsive layout: media queries and container queries

Why:A site gets opened on a phone, a laptop and a big monitor, and most often on a phone. Afterwards you’ll be able to work mobile first, choose breakpoints by content, and use container queries so a component adapts to its own place.

30 minutes

Read by speech synthesis (Qwen3-TTS); the voice is not a person’s.

Responsive design is one site that adapts to any screen with media queries. Container queries adapt a component to the width of its parent.

One site for every screen

In 2007 the iPhone arrived, and sites that looked fine on a laptop suddenly found themselves on a screen several times smaller. At first people built a separate mobile site at another address, such as m.example.com, and kept two copies. That was expensive and confusing. In 2010 the American designer Ethan Marcotte described another path and called it responsive web design: one site, one HTML, and the look adapts to the screen. It has three parts:

  1. a fluid grid: column widths in proportions, not pixels;
  2. flexible images, which shrink together with their column: img { max-width: 100%; height: auto; };
  3. media queries: rules that switch on at a certain width.

Two conventions joined them. The viewport: the line <meta name="viewport" content="width=device-width, initial-scale=1">, which you know from the lesson on the head. Without it a phone shrinks the page as if it were a “wide” screen, and media queries don’t fire. And mobile first, an idea of Luke Wroblewski’s (2009 to 2011): begin not from the desktop look but from the mobile one.

Mobile first and media queries

In practice, mobile first means the main rules are written for the narrow screen, and for wide screens you add to them:

/* for everyone: one column */
.layout {
  display: grid;
  grid-template-areas: "main" "aside";
  gap: 2rem;
}

/* from 48rem (768px) and wider: add two columns */
@media (min-width: 48rem) {
  .layout {
    grid-template-columns: minmax(0, 2fr) minmax(14rem, 1fr);
    grid-template-areas: "main aside";
  }
}

Why this way round and not the other? The phone gets simple code and has nothing to undo, and the extras arrive only on screens that can carry them. The condition min-width reads “this wide or wider”.

Other rules: choose breakpoints by content, not by device. Drag the window wider, and where the line gets too long and the cards too stretched, put a breakpoint. There are thousands of phone models and they keep changing, while your content stays. Write sizes in rem: then the breakpoints respect the reader’s font setting. And remember that responsive isn’t only about width: there is height, orientation, and the settings a person chooses (prefers-color-scheme, prefers-reduced-motion), which come in the next lessons.

Try it yourself: move the width and watch what happens to this page. Inside the frame are real media queries.

One page on different screens
  • The media query min-width: 48rem (768 px): does not apply, one column.
  • The card in the main block: the container is about 358 px, and the container query’s threshold is 416 px (26rem): vertical.
  • The card in the side column: the container is about 358 px: vertical.

There is one window, yet the cards behave differently: each looks at the width of its own place. That is the difference between a media query and a container query.

Check yourself: why does mobile first use min-width and not max-width?

The main rules are for the narrow screen, and min-width adds the extras where there is more room. The phone never has to undo anything.

Container queries: adapting to your own place

A media query looks at the window. But a component doesn’t know where it will be put: the same card can end up in a wide main column and in a narrow side column, and they share one window. Until recently there was no answer, and you had to write different classes for each place.

In 2022 and 2023 container queries arrived in all browsers: a component looks at the width of its parent.

.cards {
  container-type: inline-size;
}

@container (min-width: 40rem) {
  .card {
    display: grid;
    grid-template-columns: 1fr auto;
  }
}

You declare the parent to be a “container” (container-type: inline-size, by width), and the descendant asks: “is the container wider than 40rem?” If so, the card lays out in two columns. If not, it stays vertical. Now the card can go anywhere and chooses its own look. See the diagram above: it has two identical cards in one window, and they behave differently.

Note that a container can’t be the same element that changes. The rules inside @container apply to the container’s descendants, not to the container itself.

Check yourself: how is a container query better than a media query for a card?

It looks at the width of its own place, not the window, so one card in a wide and a narrow column of the same window picks its own look.

Fingers and eyes

Responsive also means comfortable to touch. A button has to be big enough for a finger: about 44 by 44 pixels (min-height: 2.75rem). That is what Apple’s guidelines and WCAG at level AAA recommend; the minimum in WCAG 2.2 at level AA is 24 pixels. Buttons need a gap between them. The main action of your project should be visible without scrolling on a phone screen, and the button at the top of the page does that.

Practice

Make the page responsive. The preview has a width you can look at, but there is a more reliable way: open the developer tools (F12) and switch on device mode (the phone icon, Ctrl+Shift+M). There you can pick a phone and drag the width from 320 pixels.

A warning: the checks in the exercise see your page at a single width, so they can’t tell whether you wrote @media, or in which direction. They check what is visible at any width: the viewport, flexible images, the size of the button and the cards container. Watch the media query yourself by dragging the window.

What was wrong with 2014

In 2014 “responsive” often meant “squeeze the desktop look”: columns stacked, the menu in a hamburger, and the extras hidden with display: none. The text was still too small, and images still loaded at full size. The habit of writing “desktop first, then undo everything” gave the world thousands of pages where the phone parses rules that are canceled straight away.

Practice

Preparing your page…

Test

Question 1 of 6

What does responsive layout consist of, in Ethan Marcotte’s definition (2010)?

Several answers

Cards

These cards go into your review once you finish the lesson.

  • What are the three ingredients of responsive layout?

    Answer

    A fluid grid (proportions, not pixels), flexible images (max-width: 100%) and media queries. Ethan Marcotte coined the term in 2010.

  • What is mobile first?

    Answer

    The base styles are written for a narrow screen, and wide screens get more through @media (min-width: …). The phone gets simple code, and nothing has to be undone.

  • How do you place breakpoints?

    Answer

    By content: where the layout starts to break, put a breakpoint. Not by phone models. Write them in rem so they respect the reader’s font size.

  • What is a container query?

    Answer

    container-type: inline-size on the parent and @container (min-width: …) on the descendant: the component adapts to the width of its own place, not the window.

  • How big should a button be for a finger?

    Answer

    About 44 × 44 pixels (2.75rem), as Apple’s guidelines and WCAG 2.5.5 recommend. The WCAG 2.2 minimum at level AA is 24 pixels.

Sources

Next

You now know: responsive layout and mobile first, media queries, container queries.