为什么需要容器查询
媒体查询(@media)关注的是视口宽度,而组件复用时真正决定布局的往往是它自己被放进多大的容器里。同一个卡片组件,放在侧边栏(约 280px)和主内容区(约 700px)里,理想布局完全不同。容器查询(Container Queries)就是为此设计的:让组件根据自身容器的尺寸调整样式,而不是整页的宽度。
两个核心概念
- 容器(container):父元素声明
container-type,成为尺寸查询的参照物。 - 查询(
@container):子元素根据最近的容器尺寸写条件样式。
常用的 container-type 取值:
inline-size:只按行内方向(通常是宽度)查询,最常用。size:宽高都可查询,但要求容器尺寸不依赖其内容,否则会造成循环依赖,需谨慎。normal:默认值,不作为尺寸查询容器。
完整示例
<div class="panel panel--narrow">
<article class="card">
<img class="card__img" src="cover.jpg" alt="">
<div class="card__body">
<h3>标题</h3>
<p>一段描述文字。</p>
</div>
</article>
</div>
.panel {
container-type: inline-size;
container-name: card-panel; /* 可选,便于精确指定 */
}
/* 默认:窄容器下的竖向卡片 */
.card {
display: flex;
flex-direction: column;
gap: 12px;
}
.card__img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
}
/* 容器宽度达到 480px 时,改为横向布局 */
@container card-panel (min-width: 480px) {
.card {
flex-direction: row;
align-items: center;
}
.card__img {
width: 40%;
flex: 0 0 auto;
}
}
这样,卡片放进窄侧栏时是竖排,放进宽主区域时自动变横排,组件自身不需要任何改动。
几个实用要点
- 容器名称可选:不写
container-name时,@container会匹配最近的祖先容器。组件嵌套较深时,建议命名以避免歧义。 - 可以嵌套:内层容器会覆盖外层,
@container默认匹配最近的符合条件的容器。 - 单位
cqw/cqh:可用容器宽高的百分比单位做字号、间距的弹性缩放,例如font-size: 4cqw。 - 与媒体查询配合:页面级断点仍用
@media,组件级自适应交给@container,两者各司其职。 - 渐进增强:不支持容器查询的浏览器会忽略
@container规则,先保证默认样式可用,再用查询做增强。
浏览器支持与验证
容器查询已在主流现代浏览器(Chrome/Edge 105+、Safari 16+、Firefox 110+)中支持。上线前建议用 caniuse 核对目标环境,并在真机上拖动窗口或调整容器宽度实测切换效果。
小结
容器查询把"响应式"从页面维度下沉到组件维度:父级声明 container-type: inline-size,子级用 @container (min-width: …) 写条件样式。对于设计系统、可复用卡片、仪表盘小部件这类场景,它比媒体查询更贴合实际需求。