先记住这个答案
容器查询让组件根据周围给它的空间调整后代样式,而媒体查询主要根据视口或设备特征调整样式。页面是否变成双栏可以交给 @media;卡片内部图片与文字是否并排,交给 @container 更稳。尺寸查询前需要为卡片外壳指定如 container-type: inline-size,规则里的目标元素应位于这个容器内部。
- 媒体查询适合页面级布局
- 容器查询适合可复用组件
- 尺寸查询需要合格祖先容器
- 查询规则通常作用于容器后代
同一组件在不同位置复用
假设商品卡在首页主栏占 40rem,在详情页侧栏只占 18rem。两处都处于桌面视口,媒体查询会给出相同判断;容器查询却能根据卡片实际分到的宽度选择布局。
.product { container-type: inline-size; }
.product__content { display: block; }
@container (min-width: 28rem) {
.product__content { display: grid; grid-template-columns: 12rem 1fr; }
}卡片外壳提供查询基准,内部 .product__content 在足够宽时才变为图文并排。缩小侧栏不需要额外给组件传“窄模式”属性,CSS 可以根据实际空间处理。
浏览器寻找的是目标元素祖先中的合格容器。若卡片内部还有另一个更近的查询容器,无名查询可能改查那一层,需要用 container-name 明确指定。
页面骨架仍然需要媒体查询
容器查询不取代媒体查询。整页导航折叠、视口高度变化、打印模式等需求还是页面或设备环境问题;卡片、搜索框、评论区等复用组件更适合按自身可用空间响应。
两者可嵌套,让规则同时要求大屏环境和宽组件。只要组件宽度就能决定时,不要再加视口条件,否则组件在新页面里可能意外失效。
容器查询的“容器”不是任意父元素。示例里必须先让 .product 成为尺寸查询容器;否则 @container 没有合格祖先,即使 .product__content 在宽主栏里也不会切成两列。反过来,若页面外层已经有一个更近的容器,内部规则可能测到它。复用组件时把查询容器写在组件外壳,并在主栏、窄侧栏、弹窗三处检查,是验证边界最直接的办法。
容易答错的地方
- 认为
@container查询目标元素自己 - 尺寸查询通常查看目标的祖先容器。给目标自己加容器类型,并不能让它直接根据自己宽度修改自己。
- 认为容器查询能完全代替媒体查询
- 窗口级导航、打印媒体、用户偏好等条件仍属于
@media擅长的范围。
面试官还会怎么问?
为什么尺寸查询要求 container-type?
它提供稳定的查询尺寸,避免后代样式又反过来改变用于判断的容器尺寸。
不指定名字会查询谁?
通常选最近的合格祖先容器。多层嵌套时可给目标层命名。
一个组件里能同时用两种查询吗?
可以。嵌套时两组条件都要成立,适合同时依赖页面环境和组件空间的规则。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。