容器查询核心语法与浏览器支持现状
CSS容器查询(Container Queries)是前端响应式设计的范式升级——媒体查询@media根据视口宽度调整布局,容器查询@container根据父容器宽度调整布局。这解决了组件库开发中的核心痛点:同一个组件在不同侧边栏宽度下需要不同布局,但媒体查询只能感知视口而非容器。容器查询让组件真正做到”放在哪里都能自适应”。
/* 定义容器查询上下文 */
.card-container {
container-type: inline-size;
container-name: card;
}
/* 根据容器宽度切换布局 */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
gap: 1rem;
}
}
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
.card__image {
width: 100%;
aspect-ratio: 16 / 9;
}
}
container-type有三种值:inline-size(只监听宽度变化,性能最优)、size(同时监听宽高)、normal(不作为容器)。大多数场景用inline-size足够,避免使用size造成不必要的重排。浏览器支持:Chrome 105+、Firefox 110+、Safari 16+,2024年起主流浏览器已全面支持。
容器查询单位cqw/cqh与流式排版
容器查询单位(cqw、cqh、cqi、cqb等)基于容器尺寸而非视口尺寸计算,类似vw/vh但参照容器。1cqw等于容器宽度的1%。
/* 使用容器单位实现流式排版 */
.sidebar-widget {
container-type: inline-size;
}
.widget-title {
font-size: clamp(1rem, 4cqw, 2rem);
/* 字号在1rem到2rem之间,按容器宽度4%缩放 */
}
.widget-content {
padding: 2cqw;
/* 内边距随容器宽度变化 */
}
@container (min-width: 300px) {
.widget-grid {
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}
}
clamp()配合容器单位实现平滑缩放,不需要定义多个断点。这种方式比多个@container断点+固定字号更优雅,特别适合组件需要在不同宽度侧边栏中展示的场景。cqi(inline方向)和cqb(block方向)是逻辑单位,在RTL语言和竖排书写模式下自动适配方向。
组件库中的容器查询实践模式
设计系统中的组件需要在Dashboard侧边栏、弹窗、全宽页面等多种容器中复用。传统做法是传入size prop控制布局,组件内部通过条件判断渲染不同结构。容器查询让组件CSS直接响应容器尺寸,JS无需感知布局逻辑:
<!-- React组件:不传size prop,CSS自适应 -->
function ProductCard({ product }) {
return (
<div class="product-card-wrapper">
<article class="product-card">
<img class="product-card__img" src={product.image} alt={product.name} />
<div class="product-card__body">
<h3 class="product-card__title">{product.name}</h3>
<p class="product-card__price">{product.price}</p>
<button class="product-card__cta">Add to Cart</button>
</div>
</article>
</div>
);
}
/* CSS: 组件自身处理所有布局变体 */
.product-card-wrapper {
container-type: inline-size;
container-name: product-card;
}
/* 窄容器:竖排 */
@container product-card (max-width: 299px) {
.product-card { flex-direction: column; text-align: center; }
.product-card__img { width: 100%; }
}
/* 中等容器:横排紧凑 */
@container product-card (min-width: 300px) and (max-width: 499px) {
.product-card { display: grid; grid-template-columns: 120px 1fr; }
}
/* 宽容器:横排宽松 */
@container product-card (min-width: 500px) {
.product-card { display: grid; grid-template-columns: 200px 1fr; gap: 2rem; }
}
组件库中使用容器查询的收益:减少组件props数量(不再需要size/variant/layout等布局相关props);主题一致性——所有使用该组件的地方自动获得一致的响应式行为;维护集中——布局逻辑在CSS中,修改一处全项目生效。
容器查询与媒体查询的组合策略
容器查询并非替代媒体查询,两者解决不同层次的问题。媒体查询处理页面级布局(导航栏、侧边栏显隐、页面整体列数),容器查询处理组件级布局(卡片在容器内横排还是竖排)。组合使用:
/* 页面级:视口窄时侧边栏收起 */
@media (max-width: 768px) {
.layout { grid-template-columns: 1fr; }
.sidebar { display: none; }
}
/* 组件级:无论视口多宽,侧边栏内的组件按自身容器调整 */
.sidebar {
container-type: inline-size;
}
@container (min-width: 280px) {
.nav-item { flex-direction: row; }
}
@container (max-width: 279px) {
.nav-item { flex-direction: column; }
.nav-item__label { display: none; }
}
侧边栏宽度由页面布局决定(媒体查询),侧边栏内部组件布局由容器查询处理。两者各司其职,不互相干扰。这种分层策略让页面级响应式和组件级响应式解耦,修改页面布局不影响组件内部表现。
容器查询的样式查询Style Queries进阶用法
CSS Style Queries(@container style())查询容器的自定义属性值,实现基于主题状态的条件样式。Chrome 111+已支持:
/* 父容器通过CSS变量控制子组件样式 */
.theme-wrapper {
--theme-mode: dark;
container-type: inline-size;
}
@container style(--theme-mode: dark) {
.child-card {
background: #1a1a2e;
color: #e0e0e0;
border-color: #2d2d44;
}
}
@container style(--theme-mode: light) {
.child-card {
background: #ffffff;
color: #1a1a2e;
border-color: #e0e0e0;
}
}
/* 配合JS切换主题:只需修改父容器CSS变量 */
document.querySelector('.theme-wrapper').style.setProperty('--theme-mode', 'light');
Style Queries无需container-type声明即可使用,因为它查询的是样式而非尺寸。适用场景:主题切换、密度模式(compact/comfortable)、强调状态(highlighted/muted),不需要在DOM上添加额外class,仅通过CSS变量传递状态。
性能注意事项与调试技巧
容器查询的性能影响主要来自容器尺寸变化时的重排。container-type: inline-size只监听宽度变化,性能优于size(宽高都监听)。避免嵌套容器查询过深——每层容器尺寸变化都触发子容器重新评估。浏览器DevTools的Container查询面板可以可视化显示当前元素所在的容器及其尺寸,调试时选择元素后查看右侧Computed面板中的Container信息。
Chrome DevTools中Container信息面板展示:容器名称、容器类型、当前容器尺寸、匹配的@container规则。调试时临时修改容器宽度可以实时观察子组件布局变化,快速验证断点值是否合理。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/css-rong-qi-cha-xun-containerqueries-yu-zu-jian-ji-xiang/