容器查询与媒体查询的区别
媒体查询和容器查询是CSS响应式设计的两种机制,查询对象和应用场景不同。
核心差异对比
| 维度 | 媒体查询 | 容器查询 |
|---|---|---|
| 查询对象 | 视口(viewport) | 容器(container) |
| 查询语法 | @media | @container |
| 响应粒度 | 页面级 | 组件级 |
| 容器声明 | 无需 | 需要container-type |
| 组件复用 | 困难 | 天然支持 |
| 设计系统 | 全局协调 | 局部自治 |
查询对象差异
媒体查询:视口维度
CSS
@media (min-width: 768px) {
/* 视口宽度≥768px时应用 */
.sidebar {
width: 250px;
}
}
查询的是浏览器窗口宽度,全局共享同一值。
容器查询:容器维度
CSS
.widget-container {
container-type: inline-size;
}
@container (min-width: 300px) {
/* 容器宽度≥300px时应用 */
.widget {
display: flex;
}
}
每个容器独立查询,同一组件在不同容器中可有不同表现。
实际场景对比
同一组件在不同位置
HTML
<!-- 主内容区域(宽) -->
<main class="content-area">
<div class="card-container">
<article class="card">...</article>
</div>
</main>
<!-- 侧边栏(窄) -->
<aside class="sidebar">
<div class="card-container">
<article class="card">...</article>
</div>
</aside>
CSS
/* 媒体查询方案 */
@media (min-width: 768px) {
.card {
display: flex;
}
}
/* 问题:两个卡片样式相同,侧边栏卡片可能溢出 */
CSS
/* 容器查询方案 */
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
display: flex;
}
}
/* 主内容区卡片横向布局,侧边栏卡片纵向布局 */
组件复用场景
HTML
<!-- 设计系统中的组件 -->
<div class="component-library">
<div class="preview-panel">
<div class="container">
<div class="button">按钮组件</div>
</div>
</div>
</div>
媒体查询无法让同一按钮在不同预览尺寸下自适应。
容器查询完美解决:
CSS
.container {
container-type: inline-size;
}
@container (min-width: 200px) {
.button {
padding: 12px 24px;
}
}
@container (max-width: 199px) {
.button {
padding: 8px 12px;
}
}
查询条件差异
媒体查询条件
CSS
@media (min-width: 768px) {}
@media (max-width: 1024px) {}
@media (orientation: landscape) {}
@media (hover: hover) {}
@media (prefers-color-scheme: dark) {}
容器查询条件
CSS
@container (min-width: 300px) {}
@container (max-width: 500px) {}
@container (orientation: portrait) {}
容器查询暂不支持设备特性(hover、color-scheme等)。
组合使用策略
分层响应式设计
CSS
/* 媒体查询:页面布局 */
@media (min-width: 768px) {
.layout {
display: grid;
grid-template-columns: 250px 1fr;
}
}
/* 容器查询:组件样式 */
.sidebar {
container-type: inline-size;
}
@container (min-width: 200px) {
.nav-item {
padding: 12px 16px;
}
}
.main {
container-type: inline-size;
}
@container (min-width: 600px) {
.article-card {
display: grid;
grid-template-columns: 1fr 2fr;
}
}
各司其职
| 场景 | 推荐方案 |
|---|---|
| 页面整体布局 | 媒体查询 |
| 导航切换模式 | 媒体查询 |
| 组件内部样式 | 容器查询 |
| 设计系统组件 | 容器查询 |
| 全局字体缩放 | 媒体查询 |
| 卡片排列方式 | 容器查询 |
性能考量
媒体查询性能
- 视口变化触发全局重评估
- 规则数量影响评估时间
- 适合少量全局断点
容器查询性能
- 每个容器独立评估
- 容器数量影响评估开销
- 推荐限制容器层级深度
CSS
/* 避免:多层嵌套容器 */
.parent {
container-type: inline-size;
}
.parent .child {
container-type: inline-size; /* 增加评估复杂度 */
}
语法差异
媒体查询语法
CSS
@media screen and (min-width: 768px) and (max-width: 1024px) {
/* 媒体类型 + 媒体特性 */
}
容器查询语法
CSS
@container (min-width: 300px) {
/* 仅尺寸特性 */
}
/* 命名容器查询 */
@container sidebar (min-width: 200px) {
/* 指定容器名称 */
}
要点总结
- 媒体查询基于视口,容器查询基于父容器
- 媒体查询适合页面级布局,容器查询适合组件级样式
- 组合使用实现分层响应式设计
- 容器查询不支持设备特性查询
- 避免过深容器嵌套以保持性能
📝 发现内容有误?点击此处直接编辑