Home Frontend

CSS Container Queries: Common Mistakes and How to Fix Them

Frontend

September 16, 2026

CSS Container Queries: Common Mistakes and How to Fix Them

Container queries let a component respond to the space it has been given rather than the size of the browser window. For anything you reuse — a card, a media object, a pricing panel — that is a better mental model than a media query, and the syntax takes minutes to learn. The mistakes are the quiet ones: a rule that never fires, a card that collapses, a dropdown that jumps. These are the ones that come up most often in review, along with the fix for each.

There has to be a container in the first place

A container query only matches if an ancestor has actually been declared as a query container. Miss that step and nothing happens. No console error, no warning — just a rule that sits in the stylesheet doing nothing while you stare at it. When a container query "doesn't work", check the container before you check the query.

Two habits prevent most of this. First, put container-type: inline-size on the component's own root element rather than on some parent, so the component measures itself wherever it is dropped. Second, give it a name:

container: card / inline-size;

Now you can write @container card (min-width: 32rem) and you have eliminated a whole category of accidental matches. Unnamed queries are convenient in a demo and a liability in a codebase.

Inline size, not size

container-type: inline-size applies containment on the inline axis only, so the height still comes from the content. That is what you want almost every time: query the width, let the height look after itself.

container-type: size contains both axes, which means the element no longer sizes itself to its content at all. That is correct for a map, a canvas wrapper or a fixed-ratio tile where you control the height. It is a trap everywhere else. Put it on a card with a paragraph of copy and the card can collapse to a sliver, because nothing inside is allowed to determine its height any more. If a component suddenly has no height after you "made it a container", this is nearly always the cause.

There is a second side effect worth knowing. Containment makes the element a containing block for absolutely and fixed positioned descendants. A dropdown or tooltip that used to position itself against an outer wrapper will now pin to the new container instead. If something jumps the moment you add container-type, that is why.

Beware the nearest container

An unnamed query resolves to the nearest matching container. In a tidy demo that is fine. In a real layout — a card inside a grid inside a panel that also declares a container — your component may be measuring something three levels up that you forgot existed. The symptom is a component stuck permanently in its wide layout on a narrow screen, or permanently narrow inside a wide column.

  • Name the containers you intend to query, and query by name.
  • Remember that every element inside a container sees the same width. If an inner element needs different breakpoints, it needs its own container declaration.
  • Use the container badge in your browser's element inspector. It shows which element a rule matched, which turns a twenty-minute guess into a five-second answer.

Viewport units creep back in

The whole point of container queries is that a component stops caring about the window. Using vw in the same component quietly throws that away — a card in a narrow sidebar will still scale its padding and text with the browser width.

Container units do the job properly. cqi is 1% of the container's inline size, cqw is 1% of its width, and cqmin/cqmax pick the smaller or larger of the two axes. Reach for cqi for fluid padding, gaps and type inside components.

Two cautions. Container units also resolve against the nearest query container, so the naming advice above applies here too. And fluid type built on cqi can end up unreadably small in a tight column, so pair it with a sensible minimum via clamp() — or simply step the font size inside the container query, which is easier to reason about later.

Media queries are not obsolete

Converting every media query to a container query is a common overcorrection, and it costs you things only a media query can express. Keep media queries for page-level work: the overall grid's column count, dark mode, print styles, prefers-reduced-motion, and pointer or hover capability. Use container queries for the insides of components.

A rough rule that holds up: if the decision depends on the window or the user's environment, it is a media query. If it depends on the space the component was handed, it is a container query.

Two or three breakpoints, chosen by content

Design files hand you a pile of widths; components rarely need most of them. Start with the narrow layout as the default, then add a query at the width where the layout genuinely strains — a heading wrapping badly, a row of three stats getting cramped, a button group colliding. Two or three thresholds is normal. Five usually means the component is trying to do too much.

The same restraint applies to nesting. Each container declaration adds containment, which changes how the element sizes itself and positions its children. Nest when the inner piece has its own real layout decisions, not as a reflex.

Test by resizing the component, not the window

Dragging the browser edge only proves the page works at different widths. Select the container in DevTools and change its width, or drop the component into a narrow sidebar and a full-width column, and watch it move between layouts. Add a longer word or a longer translation to the copy as well — container queries hide their failures well until a string gets awkward.

Finally, write the default styles for the narrow layout and widen inside the query. Browsers without container query support ignore the queries entirely and get a perfectly usable stacked component, rather than a broken wide one. Wrap anything optional in @supports (container-type: inline-size) if you want to be explicit.

A short pre-flight check

  • Is there a container-type on the wrapper you actually mean to measure, and does it have a name?
  • Is it inline-size rather than size, unless the height really is fixed?
  • Are breakpoints placed where the layout breaks, not copied from a mock?
  • Have you swapped vw for cqi inside components?
  • Does the component still look right with no container query applying at all?
  • Have you resized the component itself, in a narrow column and at full width?

Work through that list and container queries stop being a source of mystery bugs and become what they should be: a small, predictable tool that makes reusable components behave sensibly wherever you put them.

Photo: alberthbq / Pixabay

Related Posts

Developer Laptop Setup Checklist for New UK Hires
Tools

October 10, 2026

Developer Laptop Setup Checklist for New UK Hires

A practical checklist for setting up a secure, comfortable development laptop as a new UK hire, from disk encryption and access requests...

read more
A Beginner's Guide to Database Normalisation for Small Business Apps
Databases

October 09, 2026

A Beginner's Guide to Database Normalisation for Small Business Apps

A practical introduction to first, second and third normal forms, with clear examples showing how to structure small business data...

read more
How to Run Zero-Downtime Database Migrations
Databases

October 07, 2026

How to Run Zero-Downtime Database Migrations

Practical steps for changing production schemas without downtime: the expand-and-contract pattern, lock-aware statements, deploy...

read more