容器查询中的命名容器与嵌套容器
命名容器解决多容器查询定位问题,嵌套容器需要理解查询匹配规则。
命名容器
为什么需要命名
无命名时,@container查询最近的祖先容器:
HTML
<div class="outer-container">
<div class="inner-container">
<div class="component">
<!-- @container查询哪个容器? -->
</div>
</div>
</div>
命名容器精确指定查询目标:
CSS
.outer-container {
container-name: outer;
container-type: inline-size;
}
.inner-container {
container-name: inner;
container-type: inline-size;
}
/* 精确查询outer容器 */
@container outer (min-width: 500px) {
.component {
padding: 24px;
}
}
/* 精确查询inner容器 */
@container inner (min-width: 200px) {
.component {
display: flex;
}
}
命名语法
CSS
/* 分开声明 */
.container {
container-name: card;
container-type: inline-size;
}
/* 简写语法 */
.container {
container: card / inline-size;
}
多容器查询示例
HTML
<div class="page-layout">
<aside class="sidebar">
<div class="widget-container">
<div class="widget">...</div>
</div>
</aside>
<main class="content">
<div class="widget-container">
<div class="widget">...</div>
</div>
</main>
</div>
CSS
.sidebar {
container-name: sidebar;
container-type: inline-size;
width: 250px;
}
.content {
container-name: main;
container-type: inline-size;
width: 800px;
}
.widget-container {
container-name: widget-box;
container-type: inline-size;
}
/* 查询页面区域容器 */
@container sidebar (min-width: 200px) {
.widget {
display: block;
}
}
@container main (min-width: 600px) {
.widget {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
}
/* 查询组件容器 */
@container widget-box (min-width: 300px) {
.widget__title {
font-size: 20px;
}
}
嵌套容器查询匹配
默认匹配规则
无命名时查询最近的符合条件的祖先容器:
HTML
<div class="level-1">
<div class="level-2">
<div class="level-3">
<div class="target"></div>
</div>
</div>
</div>
CSS
.level-1, .level-2, .level-3 {
container-type: inline-size;
}
/* 无命名查询:匹配level-3(最近) */
@container (min-width: 200px) {
.target {
padding: 16px;
}
}
命名跳级查询
CSS
.level-1 {
container: outer / inline-size;
}
.level-2 {
container: middle / inline-size;
}
.level-3 {
container: inner / inline-size;
}
/* 跳过level-2和level-3,直接查询level-1 */
@container outer (min-width: 800px) {
.target {
/* 基于level-1宽度的样式 */
font-size: 24px;
}
}
嵌套容器场景处理
组件套组件
HTML
<div class="panel-container">
<div class="panel">
<div class="card-container">
<div class="card">
<div class="card-header">...</div>
</div>
</div>
</div>
</div>
CSS
.panel-container {
container: panel-wrapper / inline-size;
}
.card-container {
container: card-wrapper / inline-size;
}
/* 面板级响应 */
@container panel-wrapper (min-width: 600px) {
.panel {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
}
/* 卡片级响应 */
@container card-wrapper (min-width: 300px) {
.card {
display: flex;
}
}
避免意外匹配
HTML
<div class="outer">
<div class="inner">
<div class="card">...</div>
</div>
</div>
CSS
/* 问题:两个容器都未命名 */
.outer, .inner {
container-type: inline-size;
}
/* @container匹配inner(最近),可能不是期望行为 */
@container (min-width: 400px) {
.card {
/* */
}
}
解决方案:命名明确意图:
CSS
.outer {
container: layout / inline-size;
}
.inner {
container: component / inline-size;
}
/* 明确查询目标 */
@container layout (min-width: 600px) {
.card {
/* */
}
}
@container component (min-width: 300px) {
.card {
/* */
}
}
容器单位与命名
容器单位cqw等始终基于最近的容器:
CSS
.outer {
container: outer / size;
width: 800px;
}
.inner {
container: inner / size;
width: 400px;
}
.target {
/* 基于inner(最近)计算 */
width: 50cqw; /* 400px × 50% = 200px */
}
容器单位不受命名查询影响,总是基于最近的容器。
多容器查询组合
同时查询多个容器
CSS
/* 查询outer满足条件 */
@container outer (min-width: 500px) {
.component {
background: blue;
}
}
/* 查询inner满足条件 */
@container inner (min-width: 200px) {
.component {
border-radius: 8px;
}
}
/* 两者同时满足时都应用 */
层叠优先级
CSS
@container outer (min-width: 600px) {
.title {
font-size: 24px;
}
}
@container inner (min-width: 300px) {
.title {
font-size: 18px; /* 后声明覆盖 */
}
}
实战案例
设计系统组件预览
HTML
<div class="preview-frame">
<div class="preview-container">
<div class="component-demo">
<div class="button">按钮</div>
</div>
</div>
</div>
CSS
.preview-frame {
container: frame / inline-size;
}
.preview-container {
container: preview / inline-size;
/* 可调整宽度预览不同尺寸效果 */
}
/* 框架级样式 */
@container frame (min-width: 800px) {
.preview-frame {
padding: 40px;
}
}
/* 组件预览级响应 */
@container preview (min-width: 200px) {
.button {
padding: 12px 24px;
font-size: 16px;
}
}
@container preview (max-width: 199px) {
.button {
padding: 8px 12px;
font-size: 12px;
}
}
嵌套容器最佳实践
分层命名约定
CSS
/* 层级命名规范 */
.layout-container {
container: layout / inline-size;
}
.section-container {
container: section / inline-size;
}
.component-container {
container: component / inline-size;
}
避免过深嵌套
CSS
/* 推荐:最多2-3层 */
.parent {
container: parent / inline-size;
}
.child {
/* 不再声明容器 */
/* 使用父级容器查询 */
}
明确查询边界
CSS
/* 每个查询使用命名 */
@container layout (min-width: 600px) {}
@container section (min-width: 400px) {}
@container component (min-width: 200px) {}
/* 避免无命名查询 */
/* @container (min-width: 300px) {} ← 不推荐 */
要点总结
- 命名容器通过
container-name或container: name / type声明 - 无命名时查询最近的祖先容器
- 嵌套容器中命名可精确指定查询目标
- 容器单位始终基于最近容器,不受命名影响
- 推荐:明确命名所有容器,避免意外匹配
📝 发现内容有误?点击此处直接编辑