先记住这个答案
container-name 用来指定 @container 应查看哪一层祖先。无名尺寸查询通常选择最近的合格查询容器;组件多层嵌套时,最近的一层可能不是想要的版心。给外层命名为 card,写 @container card (min-width: 30rem),就会从祖先链里找符合名称和查询条件的容器。名称不会创建布局,也不能代替尺寸查询所需的 container-type。
- 无名查询找最近的合格祖先
- 命名查询筛选对应祖先
- 尺寸查询还需合适的
container-type - 名称只用于查询,不改变布局
嵌套卡片为什么需要名字
侧栏本身可能设为查询容器,里面的卡片外壳也设为查询容器。卡片详情若想根据卡片宽度排版,应明确查卡片;页面标题若想根据侧栏宽度排版,应查侧栏。命名能把两种规则写得清楚。
.sidebar { container: sidebar / inline-size; }
.card { container: card / inline-size; }
@container card (min-width: 30rem) {
.card__body { display: grid; grid-template-columns: 1fr 1fr; }
}container 简写同时设置名称和类型。上面的规则作用于 .card__body,因为它是 .card 的后代;不会给 .card 自身根据自身宽度加样式。
名称只是筛选条件。页面上有多张名为 card 的卡片时,每张卡片内部的规则会找自己的祖先链,不会跑去比较另一张卡的宽度。
命名策略要稳定
为可以复用的组件外壳起与职责相关的名字,例如 card 或 sidebar,避免名字直接描述某个断点宽度。这样组件换到别的页面,内部规则仍指向同一层语义容器。
一层容器也可以有多个名字,供不同规则引用;不过名称越多,维护成本越高。调试无效规则时先检查目标是否确实是容器的后代,再检查名称拼写和查询类型。
container-name 可以写多个名称,供不同内部规则引用,但组件库里要避免过于宽泛的全局名字。比如父页面与卡片内部都叫 content,后代的 @container content 会优先找到更近的一层,搬动组件后规则可能悄悄换了测量对象。把名称放在稳定的组件边界,例如 product-card,并让负责该组件的 CSS 使用它,会比借用页面布局名更可预测。
容易答错的地方
- 认为
container-name单独就能做尺寸查询 - 只命名不会提供尺寸查询能力。要对宽度或高度查询,还需要设置合适的
container-type。 - 认为名字会跨页面寻找元素
- 容器查询沿目标元素的祖先链解析。不是像普通选择器那样从全页面找同名元素。
面试官还会怎么问?
不写名字会怎样?
浏览器会选最近的合格查询容器。层级简单时够用,嵌套复杂时容易与预期不符。
容器能给自己写 @container 样式吗?
尺寸容器通常用于查询后代,不能让自身依据自己的尺寸查询来决定自己的样式,以免形成循环依赖。
同名容器嵌套会选哪一个?
在满足类型和条件的祖先里按规则找最近的同名容器;如果要区分两层,应使用不同名称。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。