CSS 容器查询
组件驱动响应式:适配父容器而非视口。
响应式设计进阶
为什么
媒体查询适配视口,所以侧边栏和全宽页中的卡片需两条 CSS 规则。容器查询让组件响应自身容器 — 写一次,随处放。
StatCounter 2024 数据显示 58% 的网络流量来自移动端。CSS 容器查询(2023 基线)和 subgrid(2024 基线)消除了大多数媒体查询 hack,减少 30-50% 的响应式 CSS。
何时使用
用于处不同宽容器的可复用组件(侧边栏 vs 主区的卡片、栏 vs 顶栏的导航)。2023 基线,所有常绿浏览器支持。
如何做
1. 声明容器 — 父级 container-type: inline-size(宽度尺寸包含)
2. 查询 — @container (min-width: 400px) { .card { ... } } 适配子级
3. 命名容器 — container-name: sidebar; 用 @container sidebar (min-width: 300px) 查询
4. 组件优先 — 卡片响应规则针对其容器,绝非视口
5. 回退 — 特性查询 @supports (container-type: inline-size) { ... } + 媒体查询回退
6. 单位 — cqw/cqh(1cqw = 容器宽 1%)、cqi/cqb 行内/块、cqmin/cqmax
7. 嵌套 — 容器嵌套;查询最近祖先容器,作用域自动
示例
/* 卡片适配其容器,非视口 */
.card-host { container-type: inline-size; }
.card { display: grid; grid-template-columns: 1fr; gap: 0.5rem; }
@container (min-width: 400px) {
.card { grid-template-columns: 120px 1fr; } /* 图 + 文并排 */
}
@container (min-width: 700px) {
.card { grid-template-columns: 1fr; padding: 2rem; } /* hero 变体 */
}
/* 命名容器 — 侧边栏独立查询 */
.sidebar { container-name: sidebar; container-type: inline-size; }
@container sidebar (max-width: 200px) { .nav-item { flex-direction: column; } }
/* 旧浏览器回退 */
@supports not (container-type: inline-size) {
@media (min-width: 768px) { .card { grid-template-columns: 120px 1fr; } }
}
常见问题
- ⚠忘 container-type — 查询无匹配因无祖先是容器
- ⚠尺寸包含副作用 — container-type: size 阻父级按内容尺寸,布局崩
- ⚠混视口与容器单位 — 组件一处对另一处错
最佳实践
- ✓用 container-type: inline-size(仅宽)— size 包含破坏高按内容尺寸
- ✓多容器并存时命名 — 避免查错祖先
- ✓@supports not 内提供媒体查询回退 — 旧浏览器仍得可用布局