先记住这个答案
尺寸查询需要先指定查询容器,最常用的是 container-type: inline-size。它让浏览器能用该元素的行内尺寸判断后代的 @container 规则,并避免后代样式反过来影响这个被查询的尺寸。size 同时处理两个轴,但尺寸隔离更强,若容器高度原本由内容撑开,可能需要额外给高度。默认的 normal 不支持尺寸查询。
inline-size是常用的宽度查询类型size同时支持两个轴的尺寸查询normal不提供尺寸查询能力- 查询样式作用于容器的后代
创建卡片查询容器
卡片放在主栏、侧栏时得到的宽度不同。把卡片外壳设为容器,内部详情区即可按这张卡自身的空间决定单栏或双栏,不受浏览器窗口有多宽直接支配。
.card { container-type: inline-size; }
.card__details { display: block; }
@container (min-width: 32rem) {
.card__details { display: grid; grid-template-columns: 1fr 1fr; }
}当 .card 的行内尺寸达到阈值,它的后代 .card__details 变成两列。把 container-type 写到 .card__details 自己身上,不能让它直接根据自身宽度改变自身样式。
inline-size 是逻辑轴概念。在常见横排文字中是宽度;竖排书写模式里则对应另一物理方向。讨论容器查询时应说行内轴,而不是无条件说水平宽度。
为什么还有 size
如果组件确实要同时根据容器的行内尺寸和块尺寸判断,可以选 size。但它对两个轴都有尺寸隔离:容器块尺寸不再直接由后代内容决定。若原本依靠内容把盒子撑高,改成 size 后可能出现高度问题。
优先用满足需求且影响最小的 inline-size。需要命名时可加 container-name 或使用 container 简写;名字便于选中正确祖先,但不会单独开启尺寸查询。
inline-size 引入的尺寸隔离还有一个直观后果:容器自己的行内尺寸不能再靠后代内容反推。它通常由父布局分配宽度,所以普通卡片用起来顺手;但若外层本来依赖“内容有多宽,盒子就有多宽”,加上容器类型后可能改变原先的收缩效果。给包装层设容器、让实际内容在其后代里响应,往往比直接给需要自适应宽度的元素设容器更稳。
容易答错的地方
- 只写
container-name就查尺寸 - 名称只筛选祖先。尺寸查询还需要容器具备相应的
container-type。 - 把
size当成无副作用的加强版 - 双轴尺寸隔离会影响内容撑开容器的行为。只按宽度响应时,用
inline-size通常更合适。
面试官还会怎么问?
normal 的容器还能做样式查询吗?
样式查询与尺寸查询的要求不同。做自定义属性的样式查询时,普通非空元素也可成为候选样式容器。
为什么查询没命中?
依次检查目标是否是容器后代、实际行内尺寸是否达到阈值、是否存在更近的合格容器。
能给容器自身按其宽度改样式吗?
尺寸查询主要作用于后代,不能让容器用自己的尺寸查询直接决定自身样式,避免循环依赖。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。