CSS容器查询实战:让组件自适应容器而不是视口

阿乐
阿乐 管理员 黑卡会员
发布于 2026-09-06 14:54 ·1 浏览 ·0 回复

我们可能已经习惯了用媒体查询来适配视口宽度,但当同一个组件被塞进侧边栏、主内容区甚至弹窗里时,视口尺寸并不能决定一切。CSS容器查询带来的核心思路是:让组件根据“自己所在的容器”来调整布局。组件终于不是仰望视口,而是低头看自己的地盘了。

从媒体查询到容器查询

媒体查询问的是“屏幕现在多宽?”,而容器查询问的是“我的容器现在多宽?”。这在组件化开发中非常实用。同样一个商品卡片,在首页宽大的内容区里可以左图右文,在侧边栏那 240px 的窄空间里却只适合上下堆叠。过去我们要用媒体查询把断点绑定到全局视口,导致组件在不同页面复用时反复打补丁。容器查询允许我们把断点下沉到组件边界,真正实现“组件自治”。

基础用法

要让某个祖先元素成为可查询的容器,需要给它声明一下:

.card-container {
  container-type: inline-size;
  container-name: product;
}

`container-type: inline-size` 表示只关注容器的宽度方向,避免生成不必要的布局约束。然后就能用 `@container` 了:

@container product (min-width: 400px) {
  .card .info {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}

这里的 `min-width` 不再是视口宽度,而是 `.card-container` 的实际内容宽度。建议在复杂项目里给容器起个明确名字,否则它会查询最近一层未命名的容器,稍不留神就容易作用到错误节点上。

实战例子

假设我们有一套文章卡片组件,它既会出现在宽达 600px 的主内容区,也会出现在只有 240px 的侧边栏里。先给它的父层定义容器:

.widget {
  container: article-card / inline-size;
}

卡片结构大约是图片、标题、摘要。默认情况下,图片在上、摘要在下,适合窄场景:

.article-card__body {
  display: flex;
  flex-direction: column;
}

.article-card__summary {
  display: none;
}

当容器宽度达到 300px 时,宽场景足够容纳横排布局,于是切换成左右结构并显示出摘要:

@container article-card (min-width: 300px) {
  .article-card__body {
    flex-direction: row;
    align-items: center;
  }

  .article-card__summary {
    display: block;
  }
}

注意,这里的断点与视口无关。哪怕视口只有 320px,只要该组件所在容器足够宽,它就仍然可以横排展示。这就是组件级响应式的底气。

容器查询还带来了对应的容器单位,例如 `cqw` 代表容器宽度的 1%,`cqh` 代表容器高度的 1%。我们可以让标题字号跟着容器走:

.card-title {
  font-size: 3cqw;
}

这种动态行为在封装通用组件时堪称降维打击,比靠 JS 测量尺寸再改样式要干净得多。

一些坑和限制

容器查询会让被标记的元素创建新的包含块和层叠上下文,部分绝对定位的子元素位置可能会变,需要测试。若没有特殊需求,尽量用 `inline-size` 而不是 `size`,后者要求容器必须有确定的高度,否则容器自身会塌陷

全部回复 0

还没有回复,来抢沙发~