配了三年组件库,每次把同一个卡片放进不同布局都要重写媒体查询——今天 @container 把这件事从根上彻底变了
配了三年组件库,每次把同一个卡片放进不同布局都要重写媒体查询——今天 @container 把这件事从根上彻底变了。
你也在写 .card–sidebar 吗?
有没有这种感觉:一个 Card 组件,明明逻辑一样,但放在侧边栏是一个样子,放在主内容区又是一个样子,放在 Modal 里又要再加一套样式。于是你开始写 .card–sidebar、.card–hero、.card–modal,然后发现这套补丁永远打不完。
这不是你代码写得烂,是响应式设计的旧范式到头了。
十年来我们用 @media 做响应式,但 @media 只能感知视口宽度。一个 1200px 的视口下,侧边栏里的卡片只有 300px 可用,你的媒体查询却以为它有 1200px——这个矛盾无解,直到 @container 出现。
@container 是什么
@container 让 CSS 能查询「元素父容器」的宽度,而不是视口。
三步上手:
第一步:声明容器
.card-wrapper { container-type: inline-size; container-name: card; }
inline-size 是最常用的值,只查询容器宽度(横向尺寸),不强制约束高度。container-name 给你一个命名空间,防止嵌套容器时规则冲突。
第二步:写容器查询
/ 默认:窄容器里竖着排 /
.card { display: flex; flex-direction: column; gap: 1rem; }
/ 容器宽度 ≥ 400px 时横排 /
@container card (min-width: 400px) { .card { flex-direction: row; align-items: center; } }
/ 容器宽度 ≥ 600px 时放大内边距 /
@container card (min-width: 600px) { .card { padding: 1.5rem; } }
第三步:放哪都行
同一个组件,往主内容区塞、往侧边栏塞、往 Modal 里塞——它自己会根据父容器宽度适配,你不用改一行 CSS。
这就是真正的「组件级响应式」:样式跟着组件走,不是跟着页面走。
真实项目里省了多少代码
上面那个 47 个组件的设计系统,接入容器查询之后:
删掉了 .card–sidebar、.card–compact 等 23 个组件变体
删掉了选择这些变体的 JavaScript 逻辑
组件在不同布局里「自适应」,不需要外部容器感知组件应该显示什么样式
不只是 Card。导航栏(侧边栏里折叠、主内容区展开)、产品网格、表单布局——所有之前需要「感知自己在哪种布局里再决定怎么渲染」的组件,都可以用同样的模式处理。
容器查询专用单位:cqi / cqb
和 vw/vh 类似,容器查询也有一组相对单位:
.card-title { font-size: clamp(1rem, 5cqi, 2.5rem); }
.card-image { height: 30cqi; }
cqi = container query inline size(容器宽度),cqb = block size(容器高度)。用这些单位做流体排版,字号和间距会跟着组件所在的容器宽度平滑缩放——而不是跟着视口。
浏览器支持:2026 年不用 polyfill 了
@container (size):Chrome 105+、Firefox 110+、Safari 16+,全球覆盖率约 94%
@container style():2026 年 5 月进 Baseline,Chrome 111+、Firefox 151+、Safari 18+ 支持,约 90% 覆盖
容器查询单位 cqi/cqb:Chrome 105+、Firefox 110+、Safari 16+,约 94% 覆盖
style() 查询(根据 CSS 变量值做条件样式)是较新特性,部分浏览器还需实验开关。但基础的尺寸查询在 2026 年已经是全平台覆盖,不需要任何 polyfill。
下一步:找一个组件开始迁移
不需要一次全改。找一个你维护的组件,它的样式里有没有 .component–variant 之类的媒体查询变体?把它的父容器加上 container-type: inline-size,把 @media 换成 @container,然后把它放进不同宽度的父容器里试试。
如果你的组件库里用的是 CSS-in-JS 或者 Tailwind,这套思路同样适用——关键是先找到一个「需要在不同布局上下文里有不同表现」的组件,然后让组件自己感知自己的容器宽度,而不是让外部来决定它应该显示什么。
这件事从 2023 年就可以做了,但 2026 年的今天,浏览器支持已经是 94%+,没有理由再等了。
核心就一句话:媒体查询问「屏幕有多宽」,容器查询问「我被放在哪里了」。组件需要回答的是第二个问题。
评论区
登录后可评论。