Container Queries
After this lesson you'll build components that style themselves by their container's size — so a single card works in a wide column or a narrow sidebar without a single media query.
Part of the free HTML & CSS course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn
Prerequisites: You should be comfortable with selectors from CSS Basics & Selectors and have met @media queries for responsive design. Container queries are the component-level upgrade to that idea.
💡 Real-World Analogy
Think of a media query as dressing for the weather forecast for the whole city : everyone hears "it's cold downtown" and puts on a coat, even the person sitting in a warm room. A container query is dressing for the room you're actually in — you check the temperature where you are and react to that.
A card component is the person. With media queries it dresses for the screen size (the city forecast), which is wrong when it's placed in a narrow sidebar on a big monitor. With a container query it dresses for its own container (the room), so it always fits — wherever you drop it.
📊 Media Query vs Container Query
Feature
Media Query
Container Query
Measures
Viewport (screen) size
A parent container's size
Reusability
⚠️ Tied to page layout
✅ Works wherever you place the component
Syntax
@media (min-width: 400px)
@container (min-width: 400px)
Setup needed
None
container-type: inline-size on the parent
1. Make a Container, Then Query It
Container queries are a two-step deal. First you mark an element as a query container with container-type: inline-size — this says "measure my width so my children can ask about it." inline-size means width-only containment, which is what you want almost every time. Optionally give it a name with container-name so you can target a specific container later.
Then, on a child , you write an @container rule: @container card (min-width: 400px) { … } . The browser checks the nearest ancestor that is a container and applies those styles when its width crosses the threshold. Run the example — the same card is vertical in the narrow panel and horizontal in the wide one, with no media query anywhere.
2. Container Query Units (cqw, cqh, cqi, cqb)
Queries flip layouts at breakpoints; container units let you scale things smoothly with the container. They mirror viewport units, but relative to the query container instead of the screen: cqw is 1% of the container's width, cqh is 1% of its height, and cqi / cqb are the writing-mode-aware versions (inline/block — width/height in normal left-to-right text).
They pair beautifully with clamp() : font-size: clamp(1rem, 5cqi, 3rem) means "5% of the container's width, but never smaller than 1rem or larger than 3rem." Resize the box below and watch the text and bar respond to the container , not the window.
🎯 Your Turn 1 — Make It a Container
The @container rule is already written, but it never fires because the wrapper isn't a container yet. Add the two lines ( container-type and container-name ) so the badge turns green. The expected result is in the comments.
🎯 Your Turn 2 — Write the Query and a Unit
Containment is set up for you. Now write the @container breakpoint and use a cqi unit: make the heading scale with the container, and switch the tile to two columns when the container is at least 450px wide. Fill in the three blanks.
🧩 Mini-Challenge — A Self-Adapting Profile
Now without the blanks. Build a profile component that stacks vertically by default and goes horizontal (with a larger, cqi -scaled name) once its container passes 380px — then drop the same markup into a narrow frame and a wide frame. No media queries allowed. The brief and expected result are in the comments.
Container or Media Query?
- Container query: any reusable component (card, widget, media object) that might live in columns of different widths.
- Container units: type or spacing that should scale fluidly with the component's own width.
- Media query: page-level decisions — overall margins, how many columns the whole page has.
- Media query: device-level concerns — print styles, prefers-reduced-motion , prefers-color-scheme .
- Both together: media query sets the page's column count; each column's components adapt with container queries.
Common Errors
- Forgetting container-type . Symptom: your @container block is ignored and nothing changes. Cause: no ancestor is a container. Fix: add container-type: inline-size to the wrapper element you want to query.
- Querying the element itself. Symptom: you put container-type and the @container styles on the same element and it doesn't react. Cause: an element can't query its own size. Fix: put containment on a wrapper and style the child inside it.
- Naming mismatch. Symptom: @container card (…) never matches. Cause: the container's container-name isn't card (or you have a typo). Fix: match the names exactly, or drop the name from the query to target the nearest container of any name.
- Assuming no fallback / ignoring old browsers. Container queries are Baseline in 2026, but if you support legacy browsers the @container block is simply skipped there. Fix: make the styles outside the query a complete, sensible default so the component still works as a progressive enhancement.
📋 Quick Reference — Container Queries
What
Syntax
Does
Enable (width)
container-type: inline-size;
Makes the element a width-query container
Enable (both axes)
container-type: size;
Width + height queries (element needs explicit height)
Name it
container-name: card;
A name so a query can target this container
Shorthand
container: card / inline-size;
Sets name and type in one line
Query
@container card (min-width: 400px) { … }
Styles a child when the container is wide enough
Units
cqw cqh cqi cqb
1% of container width / height / inline / block
💡 Rule of thumb: containment goes on the wrapper ; the @container styles and cq* units go on the children inside it.
Frequently Asked Questions
🎉 Lesson Complete
- ✅ Container queries style components by their parent's size, not the viewport
- ✅ Step 1: container-type: inline-size (and optional container-name ) on a wrapper
- ✅ Step 2: @container (min-width: 400px) on a child to flip its layout
- ✅ cqw / cqh / cqi / cqb scale things to the container, like vw/vh do for the screen
- ✅ Containment goes on the wrapper — an element can't query its own size
- ✅ Media queries still own page-level and device-level decisions; use both together
What's next: take control of which rules win across your stylesheet in CSS Cascade & Layers .
Practice quiz
What does a container query measure, compared to a media query?
- The viewport size
- A parent container's size
- The font size
- The device pixel ratio
Answer: A parent container's size. A container query reacts to an ancestor container's size; a media query reacts to the viewport.
Which declaration turns an element into a width-query container?
- container-type: inline-size
- container: width
- query-type: width
- display: container
Answer: container-type: inline-size. container-type: inline-size makes the element a width-query container so children can query it.
Why might an @container rule do nothing?
- The browser is too old
- No ancestor has container-type set
- You used min-width instead of max-width
- The element is display: none
Answer: No ancestor has container-type set. An @container rule needs an ancestor with container-type set; without one, there's nothing to query.
Can an element query its own size with a container query?
- Yes, always
- No — containment goes on a wrapper, not the styled element
- Only with container-type: size
- Only in Firefox
Answer: No — containment goes on a wrapper, not the styled element. An element can't query itself; you put container-type on a wrapper and style the child inside it.
What does the unit 50cqi represent?
- 50% of the viewport width
- 50 pixels
- 50% of the container's inline size (width in LTR text)
- 50% of the container's height
Answer: 50% of the container's inline size (width in LTR text). cqi is 1% of the container's inline size, so 50cqi is half the container's width in left-to-right text.
Which container unit corresponds to 1% of the container's height?
- cqw
- cqh
- cqi
- cqb
Answer: cqh. cqh is 1% of the container's height; cqw is 1% of its width.
What is the correct syntax to target a named container in a query?
- @container card (min-width: 400px)
- @container (name: card) (min-width: 400px)
- @media card (min-width: 400px)
- @query card { min-width: 400px }
Answer: @container card (min-width: 400px). Place the container name right after @container: @container card (min-width: 400px) { … }.
What does container-name let you do?
- Set the container's width
- Target a specific container in an @container rule
- Make the container scrollable
- Disable inheritance
Answer: Target a specific container in an @container rule. container-name labels a container so an @container query can target that specific one.
For which task is a media query still the right tool over a container query?
- Adapting a reusable card
- Scaling a heading with its parent
- Page-level decisions like print styles or prefers-color-scheme
- Switching a widget to two columns
Answer: Page-level decisions like print styles or prefers-color-scheme. Media queries remain best for device/page-level concerns like print styles and prefers-color-scheme.
What is the shorthand to set both container name and type in one line?
- container: card / inline-size
- container-all: card inline-size
- container-type: card inline-size
- container-shorthand: card, inline-size
Answer: container: card / inline-size. container: card / inline-size sets the container-name and container-type together.
Continue this course
- Previous: CSS Grid Level 2
- Next: CSS Cascade & Layers