Stop Treating CSS Container Queries Like Traditional Media Queries — Smashing Magazine


To be completely honest with you, I missed the news when CSS Container Queries first shipped. And when I finally heard about it, my very first thought was, “Why exactly do I need this when media queries already exist?”

I’m not proud of that reaction, knowing what I know now, but it was comforting to know that I wasn’t alone. In fact, there are legions of us out there.

What baffles me is that container queries aren’t a new feature, as it currently sits at around 94% browser support. And yet, very few people are actually using it. According to the State of CSS survey, 86% of developers are aware of container queries, but only 41.4% actually use them. Surveys can be biased and not completely representative of our entire field, but this one is certainly the best indicator we’ve got.

Kevin Powell also talked about this at SmashingConf Amsterdam 2026: Container Queries adoption has been terrible. And that is so strange to me, knowing that the ability for components to adapt to the size of their outer container has been at the top of so many CSS wishlists over the years.

I’m not particularly interested in how many people are using container queries as much as in how they are using them. I can’t account for everyone, but from what I’ve seen — including in my own early attempts — many of us are using them wrong.

The bottom line is that incorrect use comes down to the same impression I had when learning about them: they absolutely look just like media queries at first glance. And since they look similar, it’s easy to assume they serve similar purposes and work the same way.

They don’t.

Note: I should state up front that what I’m focusing on in this article is using container size queries, i.e., a responsive design technique for responding to the size of a particular container. There are also container style queries that respond to a container’s computed styles (and are experimental at the time of this writing). You can catch up on those in Juan Diego’s piece here on Smashing Magazine where he examines their possible use cases.

The viewport is a proxy. It always has been. Media queries are what gave us the illusion that screen width alone is responsible for how responsive apps adapt to their environment.

Ask yourself this: When you write @media, what are you asking the browser?

@media (min-width: 1024px) {
  .card {
    display: flex;
  }

I, like most developers, am asking the browser: How wide is the screen right now? That’s it.

Media queries answer that beautifully, but what happens when this .card component is placed in a grid cell that’s 300px wide on a 1920px desktop screen?

The media query doesn’t care; it does its job. The viewport is still 1920px, so min-width: 1024px fires and the matched query styles are applied, even though the card only has 300px of space to work with. Eventually, everything in the card deforms, overflows, or cramps up.

“Media queries are dumb. Not dumb in terms of the concept, but dumb in that they don’t know very much. In fact, most people assume that they know more than they do.”

— Kevin Powell

It’s common to think of responsive design purely as a system for updating complete page layouts, like going from two columns on a large screen to a single column on a small screen.

Container Queries Look Inward

Container queries are smarter than that. They make responsive layouts more reliant on what’s happening inside a component rather than on the outer context that has no insight into a component’s contents. It is more like: “How much space is available for me in this specific spot, right now?”

Here is the same card code example we looked at in the last section, but with a container query:

.card-wrapper {
  container-name: card;
  container-type: inline-size;
}

@container card (min-width: 450px) {
  .card {
    display: flex;
    flex-direction: row;
  }
}

This changes everything. The card isn’t influenced by the viewport; its only concern is whether the .card component’s parent wrapper has at least 450px of inline (i.e., horizontal in a left-to-right writing mode) space. If that condition is true, the component goes horizontal; if not, it goes to its default block display.

See the Pen [Viewport vs Container [forked]]( by Vayo.

See the Pen Viewport vs Container [forked] by Vayo.

“Macro” Layout Vs. “Micro” Layouts

A very interesting way to distinguish @media and @container queries is the layout type.

Media queries are for the “macro” layout; they look outward. Stuff like page structure, the header that spans the window, footers, main grid layout, system preferences (prefers-color-scheme), device capabilities (touch screens). You know, anything that is majorly true to the entire page structure.

Container queries, I’d say, are for “micro” layouts, i.e., most things that live inside the “macro” layout. We use them when any content needs to responsively fit whatever space it is allocated. Components that come to mind are things like cards, widgets, forms, navigation, and so on.

In other words, think “page layout” vs. “component layout”.

An element shouldn’t magically become “tablet-sized” just because the width exceeds an abstract width threshold like 768px. Instead, it should switch layout when it has enough space to do so, whether that happens on a mobile viewport or inside a desktop sidebar.

In case you’re still not convinced, did you know there are over 2,300 unique viewport sizes on the modern web? Do you think it is possible to account for all of them?

I’m not hating on media queries. It’s that in this era of responsiveness and component re-use, layout logic is closer to the container than the viewport. When we think in terms of containers and components, we’re effectively relying on the content to determine layout, not the viewport.

This is how it should be.

Example: Fluid Typography Inside A Component

Responsive typography is a good example of something many of us have relied on media queries for. The fact that media queries come with their own CSS units — e.g., vw, vh, and so on — that are relative to the viewport size makes media queries look really good for adjusting font size based on the user’s screen size.

.card-title {
  font-size: clamp(100%, 1rem + 2vw, 24px);
}

This works until that same component is moved into a different context, like a sidebar, where the viewport is completely irrelevant. Now, because we tied the responsiveness to the wrong reference point, the scaled typography can get too big or too small.

Container queries come with their very own units — cqi, cqw, cqb, among others — and we can take responsive components further by coupling those units with the CSS clamp() function, using it for fluid typography that scales with the component rather than the viewport:


.card-title {
  font-size: clamp(1rem, .5rem + 3cqi, 2rem);
}

See the Pen [Fluid Typography [forked]]( by Vayo.

See the Pen Fluid Typography [forked] by Vayo.

With this in place, the entire code is self-contained to that element’s specific container.

Example: Flexbox Wrap Detection

Interestingly, container queries can, in a way, detect the state of a component’s internal layout. It’s not bulletproof, but it is also something media queries simply cannot do because they only observe the external browser window and are structurally blind to internal layout events like when, for example, flex items wrap onto a new line. Let’s poke at that.

Flexbox is superb at wrapping content (flex-wrap: wrap), allowing flex items to automatically wrap to new lines when the flex container runs out of space to fit them in a single row. But CSS by itself can’t tell when that wrap happens. There isn’t something like a :wrapped pseudo-class or a media query like @media (flex-wrapped: true) that would get us there.

Media queries only observe the browser window, as they can’t see internal changes. That is pretty much what flex wrapping is: a width state change on the item itself.

For example, if you have a horizontal menu that is lined up with flexbox and you want the items to restyle themselves only when wrapped, you’d be in JavaScript territory, using ResizeObserver to get that information. However, when we nest container queries inside flex items, we can come up with a workaround to get what we need without JavaScript, thanks to this technique I learned from Kevin Powell. The core idea is to allow a flex item to flex-grow: 1 when we query the container’s inline size.

See the Pen [Fluid Typography [forked]]( by Vayo.

See the Pen Fluid Typography [forked] by Vayo.
Normal and wrapped states of two responsive items.
(Large preview)

The logic works like this:

  1. When there’s enough room, both items (.flex-item) sit side-by-side, each exactly half the parent container’s width.
  2. When there is limited space, the second item wraps to the next line.
  3. Because flex-grow is active on each item, the wrapped items stretch to fill most of the parent’s width.
  4. If the item is a container itself, it detects the sudden width expansion and fires.
/* The flex parent */
.flex-layout {
  display: flex;
  flex-wrap: wrap;
}

/* Register a flex item as a container */
.flex-item {
  container-type: inline-size;
  flex: 1 1 390px; /* Grow to fill space, wrap at 390px */
}

/* Default Card Styles (narrow / side-by-side) */
.card {
  display: flex;
  flex-direction: column;
  background: #f4f4f4;
}

/* Once there's enough room for a full row */
@container (min-width: 600px) {
  .card {
    flex-direction: row;
    align-items: center;
    background: #e2f0d9;
  }
}

This works. As the parent size shrinks and the cards wrap to two lines, the card item expands, the container query fires, and applies the necessary styles.

See the Pen [Flex Wrap Detection Using Container Queries [forked]]( by Vayo.

See the Pen Flex Wrap Detection Using Container Queries [forked] by Vayo.

Container Queries Do Have Side Effects

Container queries, like all things, come with some side effects or caveats you will want to watch for before reaching for them.

Container queries need something similar to a parent-child relationship to function as expected. Let’s say we have this markup:


We can’t actually query the .card component to adjust the .card-content, like this:

/* DOES NOT WORK */
.card {
  container-name: card;
  container-type: inline-size;
}

@container card (min-width: 400px) {
  .card {
    display: flex;
  }
}

This doesn’t work because a container cannot query itself. In that last example, we’re querying a card container and then attempting to adjust that container’s display based on its size. It’s an infinite loop.

Instead, we need an additional wrapper that makes the .card a descendant of the container:


From there, we can query the .cards container and adjust the .card layout accordingly:

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

@container cards (min-width: 400px) {
  .card {
    display: flex;
  }
}

In media queries, this doesn’t matter as @media does not care which element you style inside the block; its only concern is the viewport, which is always available. So you can just slap a condition on any element and call it a day.

2. Querying A Container’s size Could Collapse Your Layout

This happens when querying the container’s size (i.e., its block, or vertical, size) instead of its inline-size:

/* Collapses to 0px even if it has content inside */
.hero-banner {
  container-type: size;
}

Why? Because the browser calculates the container’s dimensions without looking at its children. If we don’t give the .hero-banner an explicit height (or min-height or aspect-ratio), the browser sets a height of 0px.

For that reason, it’s often better to query a container by its inline-size instead. That is, unless you genuinely need to query the container’s block size.

Media queries aren’t affected by this, as they treat height the same way they treat @media (min-height: ...) does, i.e., ask the viewport and move on.

3. Queries Cannot Accept Custom Properties

Another container query limitation: we can’t query against a custom property value:

:root {
  --breakpoint-lg: 1600px;
}

/* DOES NOT WORK */
@container (min-width: var(--breakpoint-lg)) {
  /* ... */
}

This is because custom properties depend on values that cascade down the DOM tree. There’s the possibility that a container query that relies on a custom property can change that same custom property. And it can quickly get complicated:

:root {
  --breakpoint-lg: 1600px;
}

/* DOES NOT WORK */
@container cards (min-width: var(--breakpoint-lg)) {
  .card {
    --breakpoint-lg: 1000px;
  }
}

I don’t think any project should wholesale use @container instead of @media. Media queries still play an important role in responsive layouts. It’s about understanding the separation of concerns.

I tend to reach for container queries when a component is used in more than one layout context. For example, a .card element could live in a full-width grid or a narrower sidebar. If that’s the case, then we’ll want the component’s content to determine when it adjusts rather than a media query that looks at the outer viewport.

Similarly, I reach for media queries when a component solely exists at the page level. This would be something like a main navigation that always sits at the top of the page. It is directly influenced by the viewport’s size, meaning that the viewport is a reliable reference for when the navigation needs to adjust. Again, it’s all about “macro” layout versus “micro” layouts.

Here’s a diagram for how I reason about which type of query to use:

Flowchart for choosing between media and container queries
(Large preview)

Conclusion

At the end of the day, the core reason why container queries look incredibly similar to media queries is simply familiarity. They’re not exactly “new”, but they are way less understood and adopted than media queries. But media queries have plenty of their own limitations; otherwise, we wouldn’t need container queries to fill those gaps.

What we have is a more effective feature for detecting when a specific component’s context changes and a means for adjusting styles based on its content, as it should be when that component can exist in multiple contexts.

Smashing Editorial
(gg, yk)





Source link

Leave a Reply

Your email address will not be published. Required fields are marked *

阿根廷对阵布基纳法索 阿根廷 - 布基纳法索 阿根廷对阵 阿根廷 阿根廷国家足球队 布基纳法索国家足球队 阿根廷国家足球队对阵布基纳法索国家足球队阵容 阿根廷比赛 哪里观看阿根廷国家足球队对阵布基纳法索国家足球队的比赛 阿根廷对阵布基纳法索 俄亥俄州立大学对阵爱荷华大学 爱荷华大学对阵俄亥俄州立大学 爱荷华大学橄榄球 杰里迈亚·史密斯 (Jeremiah Smith) 杰里迈亚·史密斯数据 爱荷华大学 俄亥俄州立大学 OSU对阵爱荷华大学 朱利安·萨因 (Julian Sayin) 爱荷华大学比赛 俄亥俄州立大学 爱荷华大学 俄亥俄州立大学七叶树队 (Buckeyes) 橄榄球 俄亥俄州立大学比分 爱荷华大学比分 俄亥俄州立大学七叶树队对阵爱荷华大学鹰眼队 (Hawkeyes) 比赛球员数据 俄亥俄州立大学七叶树队 七叶树队橄榄球 鹰眼队橄榄球 柯克·费伦茨 (Kirk Ferentz) 汉克·布朗 (Hank Brown) 俄亥俄州立大学橄榄球赛程 贾科比·杰克逊 (Ja'Kobi Jackson) 爱荷华大学鹰眼队 俄亥俄州立大学比赛在哪个频道播出 哪里观看俄亥俄州立大学七叶树队对阵爱荷华大学鹰眼队的橄榄球比赛 今天俄亥俄州立大学比赛在哪个频道播出 教士队 (Padres) 对阵酿酒人队 (Brewers) 酿酒人队 酿酒人队比赛 密尔沃基酿酒人队 酿酒人队对阵教士队 酿酒人队比分 教士队 教士队比赛 教士队今日比赛 酿酒人队今日比赛 圣地亚哥教士队 泰·弗朗斯 (Ty France) 曼尼·马查多 (Manny Machado) 威廉·孔特雷拉斯 (William Contreras) 密尔沃基 教士队 - 酿酒人队 教士队比分 特雷弗·梅吉尔 (Trevor Megill) 酿酒人队赛程 教士队 酿酒人队 梅吉尔 酿酒人队 酿酒人队比赛 酿酒人队 教士队 孔特雷拉斯 酿酒人队 教士队对阵密尔沃基酿酒人队 今日MLB比赛 Baseball Savant Lucki Lucki被刺伤 Lucki被刺伤了吗 说唱歌手Lucki Lucki遇刺事件 美国 - 墨西哥 墨西哥对阵美国 墨西哥国家队 美国对阵墨西哥 迭戈·坎皮略 (Diego Campillo) 墨西哥国家足球队 劳尔·兰赫尔 (Raúl Rangel) 友谊赛 路易斯·罗莫 (Luis Romo) 墨西哥何时比赛 墨西哥对阵美国 美国美国对墨西哥 墨西哥对阵 奥尔贝林·皮内达 迈阿密(佛罗里达州)对克莱姆森 迈阿密橄榄球 克莱姆森对迈阿密 迈阿密对克莱姆森 迈阿密飓风队 迈阿密飓风队橄榄球 达里安·门萨 迈阿密 迈阿密-克莱姆森 迈阿密大学橄榄球 克莱姆森-迈阿密 库珀·巴卡特 迈阿密对克莱姆森预测 麦克尼斯州立大学对LSU LSU对麦克尼斯 麦克尼斯橄榄球 LSU今日比赛 麦克尼斯 勇士队对道奇队 道奇队今日比赛 塔里克·斯库巴尔 道奇队赛程 勇士队今日比赛 斯库巴尔 亚特兰大勇士队对道奇队 扬基队对光芒队 德鲁·拉斯穆森 扬基队 扬基队今日比赛 坦帕湾光芒队 光芒队 扬基队比赛 纽约扬基队 扬基队今日比赛 光芒队比赛 扬基队比赛 光芒队今日比赛 NYY 扬基队-光芒队 奥斯汀·威尔斯 纽约扬基队 扬基队 阿肯色大学对德州农工大学 德州农工大学橄榄球 德州理工大学对科罗拉多大学 德州理工大学橄榄球 迪昂·桑德斯 科罗拉多大学橄榄球 德州理工大学 科罗拉多大学对德州理工大学 科罗拉多大学水牛队橄榄球 아르헨티나 대 부르키나파소 아르헨티나 - 부르키나파소 아르헨티나 대 아르헨티나 아르헨티나 축구 국가대표팀 부르키나파소 축구 국가대표팀 아르헨티나 대 부르키나파소 축구 국가대표팀 선발 명단 아르헨티나 경기 아르헨티나 대 부르키나파소 축구 국가대표팀 경기 중계 정보 아르헨티나 대 부르키나파소 오하이오 주립대 대 아이오와대 아이오와대 대 오하이오 주립대 아이오와대 미식축구 제레미아 스미스 제레미아 스미스 기록 아이오와대 오하이오 주립대 OSU 대 아이오와대 줄리안 세이인 아이오와대 경기 오하이오 주립대 아이오와대 오하이오 주립대 버키스 미식축구 오하이오 주립대 점수 아이오와대 점수 오하이오 주립대 버키스 대 아이오와대 호키스 미식축구 경기 선수 기록 오하이오 주립대 버키스 버키스 미식축구 호키스 미식축구 커크 페렌츠 행크 브라운 오하이오 주립대 미식축구 일정 자코비 잭슨 아이오와대 호키스 오하이오 주립대 경기 중계 채널 오하이오 주립대 버키스 대 아이오와대 호키스 미식축구 경기 시청 방법 오늘 오하이오 주립대 경기 중계 채널 파드리스 대 브루어스 브루어스 브루어스 경기 밀워키 브루어스 브루어스 대 파드리스 브루어스 점수 파드리스 파드리스 경기 오늘 파드리스 경기 오늘 브루어스 경기 샌디에이고 파드리스 타이 프랑스 매니 마차도 윌리엄 콘트레라스 밀워키 파드리스 - 브루어스 파드리스 점수 트레버 메길 브루어스 일정 파드리스 브루어스 메길 브루어스 브루어스 경기 브루어스 파드리스 콘트레라스 브루어스 파드리스 대 밀워키 브루어스 오늘 MLB 경기 베이스볼 사반트 럭키(Lucki) 럭키 피습 럭키가 칼에 찔렸나요? 래퍼 럭키 럭키 피습 사건 미국 - 멕시코 멕시코 대 미국 멕시코 국가대표팀 미국 대 멕시코 디에고 캄필로 멕시코 축구 국가대표팀 라울 랑헬 친선 경기 루이스 로모 멕시코 경기 일정 멕시코 대 미국 미국 미국 대 멕시코 멕시코 대 오르벨린 피네다 마이애미 대 클렘슨 마이애미 풋볼 클렘슨 대 마이애미 마이애미 대 클렘슨 마이애미 허리케인스 마이애미 허리케인스 풋볼 다리안 멘사 마이애미 마이애미 클렘슨 UM 풋볼 클렘슨 마이애미 쿠퍼 바케이트 마이애미 대 클렘슨 경기 예측 맥니스 주립대 대 LSU LSU 대 맥니스 맥니스 풋볼 오늘 LSU 경기 맥니스 브레이브스 대 다저스 오늘 다저스 경기 타릭 스쿠발 다저스 일정 오늘 브레이브스 경기 스쿠발 애틀랜타 브레이브스 대 다저스 양키스 대 레이스 드류 라스무센 양키스 오늘 양키스 경기 탬파베이 레이스 레이스 양키스 경기 뉴욕 양키스 오늘 양키스 경기 레이스 경기 양키스 경기 오늘 레이스 경기 NYY 양키스 레이스 오스틴 웰스 NY 양키스 양키 아칸소 대 텍사스 A&M A&M 풋볼 텍사스 공대 대 콜로라도 텍사스 공대 풋볼 디온 샌더스 CU 풋볼 텍사스 공대 콜로라도 대 텍사스 공대 CU 버프스 풋볼 アルゼンチン対ブルキナファソ アルゼンチン - ブルキナファソ アルゼンチン対 アルゼンチン アルゼンチン代表(サッカー) ブルキナファソ代表(サッカー) アルゼンチン代表対ブルキナファソ代表の出場メンバー アルゼンチンの試合 アルゼンチン代表対ブルキナファソ代表の視聴方法 アルゼンチン対ブルキナファソ オハイオ州立大対アイオワ大 アイオワ大対オハイオ州立大 アイオワ大フットボール ジェレマイア・スミス ジェレマイア・スミスの成績 アイオワ大・オハイオ州立大 OSU対アイオワ大 ジュリアン・サイン アイオワ大の試合 オハイオ州立大・アイオワ大 オハイオ州立大バッカイズ・フットボール オハイオ州立大のスコア アイオワ大のスコア オハイオ州立大バッカイズ対アイオワ大ホークアイズの試合・選手成績 オハイオ州立大バッカイズ バッカイズ・フットボール ホークアイズ・フットボール カーク・フェレンツ ハンク・ブラウン オハイオ州立大フットボールの日程 ジャコビ・ジャクソン アイオワ大ホークアイズ オハイオ州立大の試合の放送チャンネル オハイオ州立大バッカイズ対アイオワ大ホークアイズの視聴方法 今日のオハイオ州立大の試合の放送チャンネル パドレス対ブルワーズ ブルワーズ ブルワーズの試合 ミルウォーキー・ブルワーズ ブルワーズ対パドレス ブルワーズのスコア パドレス パドレスの試合 今日のパドレスの試合 今日のブルワーズの試合 サンディエゴ・パドレス タイ・フランス マニー・マチャド ウィリアム・コントレラス ミルウォーキー パドレス - ブルワーズ パドレスのスコア トレバー・メギル ブルワーズの日程 パドレス・ブルワーズ メギル・ブルワーズ ブルワーズの試合 ブルワーズ・パドレス コントレラス・ブルワーズ パドレス対ミルウォーキー・ブルワーズ 今日のMLBの試合 ベースボール・サバント Lucki Lucki 刺される Luckiは刺されたのか ラッパー Lucki Lucki 刺傷事件 アメリカ対メキシコ メキシコ対アメリカ メキシコ代表 アメリカ対メキシコ ディエゴ・カンピージョ メキシコ代表(サッカー) ラウル・ランヘル 親善試合 ルイス・ロモ メキシコの試合日程 メキシコ対USA アメリカ米国対メキシコ メキシコ対 オルベリン・ピネダ マイアミ対クレムソン マイアミ・フットボール クレムソン対マイアミ マイアミ対クレムソン マイアミ・ハリケーンズ マイアミ・ハリケーンズ・フットボール ダリアン・メンサ マイアミ マイアミ・クレムソン UMフットボール クレムソン・マイアミ クーパー・バーケイト マイアミ対クレムソン 予想 マクニース州立大対LSU LSU対マクニース マクニース・フットボール LSUの今日の試合 マクニース ブレーブス対ドジャース ドジャースの今日の試合 タリク・スクーバル ドジャースの日程 ブレーブスの今日の試合 スクーバル アトランタ・ブレーブス対ドジャース ヤンキース対レイズ ドリュー・ラスムッセン ヤンキース ヤンキースの今日の試合 タンパベイ・レイズ レイズ ヤンキースの試合 ニューヨーク・ヤンキース ヤンキースの今日の試合 レイズの試合 ヤンキースの試合 レイズの今日の試合 NYY