CSS @container style query 和 size query 怎么区分
来源:17golang原创
时间:2026-09-09 15:11:18 158浏览 收藏
做可复用卡片时,最容易把两个问题混在一起:卡片所在容器变窄了,应该调整布局;祖先组件传来了深色主题,应该调整颜色。前者是 size query,后者是 style query。判断口诀很简单:要比较多少宽,用尺寸查询;要读取什么 CSS 状态,用样式查询。两者都写在 @container 里,但准备条件不同。
@container (width >= 40rem)比较的是查询容器的尺寸,不是浏览器视口。@container style(--theme: dark)读取祖先的自定义属性;样式查询通常不需要设置container-type。- 同一组件可组合尺寸和样式条件,但尺寸部分仍要有
size或inline-size容器。
先看条件:size 问的是容器几宽,style 问的是容器传了什么状态
尺寸查询回答“这个组件当前可用的空间有多大”。例如同一张卡片可能出现在侧栏或主内容区,不能用全局视口宽度替它做决定。给外层声明 container-type: inline-size 后,@container 的 width 条件就会针对最近的尺寸查询容器生效。
/* 让组件按所在容器的横向空间切换布局 */
.component-boundary {
container-type: inline-size;
}
/* 容器至少有 40rem 时,卡片才采用并排布局 */
@container (width >= 40rem) {
.card {
display: grid;
grid-template-columns: 1fr 1fr;
}
}
这里的 width 是尺寸特征;也可以使用 inline-size、height、block-size、orientation 或 aspect-ratio。如果只需要横向响应,inline-size 往往比 size 更合适,因为它不会额外要求块方向尺寸参与容器查询。

样式查询关注的则是容器的计算样式。当前实际使用最稳妥的对象是 CSS 自定义属性,例如 --theme、--density 或 --surface。它不是在测量颜色,也不是在测量元素宽度,而是在询问祖先是否带有某个样式状态。
用 container-type 开启尺寸查询,用自定义属性传递样式意图
两种查询最关键的区别不在关键字,而在“查询容器如何准备”。尺寸查询要显式声明 container-type: inline-size 或 container-type: size,这是浏览器建立尺寸包含关系的入口。样式查询不要求这一步,普通非空元素也可以作为样式查询容器。
/* 主题状态由外层组件向后代继承 */
.theme-container {
--theme: dark;
}
/* style() 读取自定义属性,而不是读取容器宽度 */
@container style(--theme: dark) {
.panel {
color: #f7f8fa;
background: #18202b;
}
}
style(--theme: dark) 的值匹配依赖计算后的自定义属性。未注册的自定义属性通常按写入的 token 比较;如果需要让等价颜色值获得更稳定的比较行为,可以用 @property 声明语法和初始值。另一个容易忽略的点是继承:主题变量如果在 :root 设置,页面中大量后代都可能满足这个查询,状态边界最好放在实际组件容器上。
同一组件里如何把尺寸与主题条件组合
当卡片既要适配空间,又要跟随主题,可以把两个条件放在同一个 @container 条件里。尺寸部分依然要求存在尺寸查询容器;样式部分从可继承的自定义属性读取状态。这样组件的布局契约和视觉契约各自清楚,也避免用一个很宽的媒体查询替代所有逻辑。
/* 主题容器负责传递状态,布局容器负责提供可测量的横向尺寸 */
.component-boundary {
container: card / inline-size;
--theme: dark;
}
/* 两个条件同时满足时,panel 使用紧凑的深色并排样式 */
@container card (width >= 40rem) and style(--theme: dark) {
.panel {
display: grid;
grid-template-columns: 1fr 1fr;
background: #18202b;
}
}
不要把 @container style(max-width: 40rem) 当成“容器不超过 40rem”。它表达的是样式查询:未来若普通 CSS 声明样式查询得到支持,含义会是读取 max-width 的样式值;当前要比较实际尺寸,应写成 @container (width ,并给容器设置 container-type。

按组件约束选择 @container 写法
| 要回答的问题 | 推荐条件 | 额外准备 | 常见误用 |
|---|---|---|---|
| 卡片能否放下两列 | (width >= 40rem) | container-type: inline-size | 用视口 @media 代替容器宽度 |
| 祖先是否启用深色主题 | style(--theme: dark) | 在组件边界设置自定义属性 | 把 style() 当作尺寸比较 |
| 空间和主题都满足才改变样式 | 尺寸条件 and 样式条件 | 尺寸容器与变量状态都要存在 | 写成 style(max-width: ...) |
落地时可以按三问检查:条件来源是几何尺寸还是样式状态?查询的最近祖先是否真的是预期容器?自定义属性是否在该边界上继承到组件?旧环境需要兼容时,先保留默认样式,再用传统布局或 @media 提供可接受的基础回退。
常见问题
size query 能不能不设置 container-type?
不能依赖默认值。尺寸查询容器需要 container-type: size 或 inline-size,也可以使用对应的 container 简写。
style query 能查询普通的 color 或 max-width 吗?
当前写作范围内应优先使用自定义属性。MDN 当前示例明确以自定义属性为已支持的样式特征,普通 CSS 声明的样式查询属于后续能力描述,不要把它当作现成兼容方案。
为什么 style(--theme) 有时看起来总是匹配?
无值形式判断自定义属性是否不同于初始值;未注册变量只要被声明,后代继承后就可能满足条件。需要精确比较时给出值,必要时用 @property 注册语法。
@container 和 @media 应该怎么分工?
@media 适合页面级视口或设备条件,@container 适合组件所在容器的尺寸与样式状态。可复用组件通常优先考虑后者,页面整体布局仍可保留前者。
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
484 收藏
-
476 收藏
-
443 收藏
-
文章 · 前端 | 7小时前 | 前端 · javascript · Fetch API · 异步请求 · Fetch AbortController 响应体 Response.json AbortError248 收藏
-
339 收藏
-
308 收藏
-
154 收藏
-
127 收藏
-
352 收藏
-
381 收藏
-
204 收藏
-
282 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习