做响应式设计时,媒体查询只能根据浏览器视口宽度切换样式,但同一个卡片放进侧栏和放进主内容区,往往该有不同的排版。这时就要用 CSS 容器查询(Container Queries):让组件根据”父容器的尺寸”而非视口来响应,真正实现可复用的组件级响应式。本文从取值、写法到实战,完整跑通。
一、媒体查询的痛点:组件感知不到父容器
媒体查询的断点绑定在视口上:@media (min-width: 768px) 表示”屏幕够宽”。可组件是嵌入在布局里的——同一套卡片在 1200px 的主栏和 300px 的侧栏里,视口宽度是一样的,媒体查询无法区分,于是你只能为不同位置写多套类名。容器查询把判断对象从”视口”换成”最近的容器祖先”,组件于是能感知自己被放在了多宽的空间里。
二、@container 基本用法
分两步:先给父元素声明它是一个”容器”,再在子元素里写容器查询。核心属性是 container-type:
/* 1) 声明容器:关心宽度变化 */
.card-shell {
container-type: inline-size;
}
/* 2) 子元素依据容器宽度响应 */
.card-shell .inner {
display: block;
}
@container (min-width: 400px) {
.card-shell .inner {
display: grid;
grid-template-columns: 120px 1fr;
gap: 16px;
}
}
用 container-name 还能给容器起名,避免嵌套时选错祖先:.sidebar { container-type: inline-size; container-name: sidebar; },查询时写 @container sidebar (min-width: 300px)。
三、container-type 的三种取值
取值决定容器”测量哪个维度”,选错会导致查询永远不触发:
| 取值 | 测量维度 | 典型用途 |
inline-size | 仅inline轴(通常即宽度) | 绝大多数卡片/侧栏自适应 |
size | 宽和高都测量 | 需按高度切换(如方形变横向) |
normal | 不建立容器 | 默认值,恢复普通流 |
注意:设了 container-type 的元素,其自身尺寸不会再被后代的容器查询反向影响(避免循环),这是规范故意切断的依赖。
四、实战:一个自适应资料卡
下面这张卡片,窄容器里是上下堆叠,宽容器里变成左图右文,全程无需任何 JS、不依赖视口:
<div class="profile">
<img src="avatar.png" alt="">
<div class="meta">
<h3>星站运营官</h3>
<p>负责技术博客的设计、内容与增长。</p>
</div>
</div>
<style>
.profile { container-type: inline-size; }
.profile img { width: 64px; border-radius: 50%; }
@container (min-width: 360px) {
.profile {
display: grid;
grid-template-columns: 64px 1fr;
align-items: center;
gap: 14px;
}
}
</style>
五、容器查询 vs 媒体查询:怎么选
| 维度 | 媒体查询 | 容器查询 |
| 判断对象 | 视口/设备 | 父容器 |
| 复用性 | 低,绑定页面布局 | 高,组件自包含 |
| 适用场景 | 整体断点、导航收起 | 卡片/侧栏/组件库 |
实践上二者互补:用媒体查询处理”整站级”布局切换(如把侧栏移到下方),用容器查询处理”组件级”自适应。组件库(如你用 Vue 3 组合式 API 封装的 UI)把响应式逻辑内聚进组件,是最典型的收益点。
六、浏览器支持与优雅降级
容器查询在现代浏览器(Chrome/Edge/Firefox/Safari 近几个大版本)已全面支持。对老旧环境用 @supports 兜底:
/* 不支持容器查询时,回退到固定/媒体查询布局 */
@supports not (container-type: inline-size) {
.profile { display: flex; gap: 14px; }
}
/* 支持时再套用容器查询样式 */
@supports (container-type: inline-size) {
.profile { container-type: inline-size; }
@container (min-width: 360px) { /* ... */ }
}
七、在开发链路中落地
调试时,VS Code 配合浏览器 DevTools 的”容器查询”徽标能直观看到每个容器边界;上线后用 Nginx 反向代理 给 CSS 加长缓存(Cache-Control: max-age=31536000),让改版后的样式稳定命中。组件级响应式最大的红利,是同一个卡片在首页、文章页、侧栏里都能”放进去就适配”,不再为每个位置单独调样式。
八、小结
容器查询把响应式的判断权从”视口”交还给”组件”,是 CSS 近年最实用的能力之一。记住三步:父元素 container-type: inline-size 声明容器、用 @container (min-width: N) 写查询、用 @supports 兜底老浏览器。当你下次又想为同一组件写第二套媒体查询类名时,先想想——它是不是该用容器查询了。




