从媒体查询到容器查询的范式转变
CSS容器查询(Container Queries)是响应式布局领域近十年来最重要的演进。传统@media查询基于视口宽度调整布局,这在组件化开发中存在根本缺陷:一个组件无法根据自身所在容器的宽度自适应调整样式。当同一个侧边栏组件既出现在宽布局页面又出现在窄布局页面时,媒体查询只能根据视口宽度统一调整,组件失去了真正的响应式独立性。
@container查询解决了这个问题——它让组件根据父容器的尺寸响应,而非视口。这意味着组件是真正的自包含响应式单元,可以在任何上下文中复用而不依赖全局断点。
容器查询的基础语法与兼容性
容器查询分两步使用:先在父元素上声明容器,再在子元素中查询该容器:
/* 定义容器 */
.card-wrapper {
container-type: inline-size;
container-name: card-container;
}
/* 查询容器宽度 */
@container card-container (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
gap: 1rem;
}
}
@container card-container (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
}
container-type有三个值:inline-size(只查询宽度)、size(查询宽高)、normal(不作为容器)。inline-size性能最优,大多数场景只需要查询宽度即可。浏览器兼容性方面,Chrome 105+、Firefox 110+、Safari 16+均已支持,覆盖率超过92%。
组件级响应式的实战模式
以卡片组件为例,演示从视口响应到容器响应的重构:
<!-- 新方案:组件自包含响应式 -->
<style>
.card-wrapper {
container-type: inline-size;
container-name: card;
}
.card {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
@container card (min-width: 350px) {
.card {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
}
}
@container card (min-width: 600px) {
.card {
grid-template-columns: 180px 1fr auto;
}
.card-meta {
flex-direction: row;
gap: 1rem;
}
}
</style>
<div class="card-wrapper">
<article class="card">
<img src="thumb.jpg" alt="">
<div class="card-body">...</div>
</article>
</div>
这种模式下,同一套组件代码无论放在侧边栏、主内容区还是弹窗中,都能根据实际可用宽度自动调整布局。消除了组件对外部视口断点的耦合。
容器查询单位cqw与cqh
CSS容器查询单位(Container Query Units)是容器查询的配套特性,类似vw/vh但相对于容器而非视口:
/* 容器查询单位:1cqw = 容器宽度的1% */
.hero-title {
font-size: clamp(1.5rem, 5cqw, 3rem);
}
.hero-desc {
font-size: clamp(0.875rem, 2cqw, 1.125rem);
}
/* 容器高度查询单位 */
.sidebar {
container-type: size; /* 需要size类型才能用cqh */
}
.sidebar-item {
padding: 2cqh 1cqw;
}
cqw/cqh与clamp()函数搭配使用效果最佳,实现字体大小的流体缩放,无需定义多个断点。注意使用cqh需要container-type设为size,对性能有一定影响,应仅在需要高度响应时使用。
与CSS Layers和作用域样式的组合运用
容器查询和CSS @layer配合,可以更精细地控制样式优先级:
@layer base, components, layouts;
@layer components {
.card-wrapper {
container-type: inline-size;
container-name: card;
}
}
@layer layouts {
.sidebar .card-wrapper {
max-width: 320px;
}
.main .card-wrapper {
max-width: 800px;
}
}
布局层控制容器的最大宽度,组件层通过@container查询在容器内部自适应。这种分层策略让布局和组件的职责边界清晰:布局决定容器有多大,组件决定自己在不同大小下怎么展示。
容器查询的局限和注意事项:container-type: inline-size的元素不能自身也是flex/grid容器的查询目标(避免循环依赖);嵌套容器查询时,内层@container默认匹配最近的祖先容器,可通过container-name指定匹配外层容器;性能方面,过度嵌套容器查询会增加布局计算开销,建议容器层级不超过3层。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/css-rong-qi-cha-xun-container-shi-zhan-yu-zu-jian-ji-xiang/