LOG // 044 · CSS

CSS 容器查询踩坑记录

结论先行容器查询不是媒体查询的替代品,是组件级响应。 但它有两个副作用:container-type 会隐式加上 layout/style containment, 而且查询命中的永远是最近的祖先容器,不是元素自己。

第一次用的时候我写得很开心:卡片在窄栏里变竖排,宽栏里变横排,不用再传 props。 然后侧边栏塌了。

01它到底解决了什么

媒体查询问的是「视口多宽」,容器查询问的是「我所在的容器多宽」。 同一个卡片放进 300px 的侧栏和 900px 的主栏,可以自动长成两种样子。

02坑一:container-type 改布局

card.csscss
1.card-wrap {
2  container-type: inline-size;   /* 副作用从这里开始 */
3  container-name: card;
4}
5
6@container card (min-width: 420px) {
7  .card { grid-template-columns: 120px 1fr; }
8}
Warn

加了 container-type: inline-size 的元素,高度不再由内容撑—— 它变成了一个「inline 方向可查询、block 方向由内容决定」的盒子。我那个侧边栏是靠子元素撑高的,加上之后直接没了高度。

03坑二:查询的是父级,不是自己

@container 写在哪个元素上,查的是它祖先里最近的容器。 所以下面这段不会生效——.card 自己是容器,它查的是外层。

card.css(错误示范)css
1.card {
2  container-type: inline-size;
3}
4
5/* 这个查询命中的是 .card 的祖先容器,不是 .card 本身 */
6@container (min-width: 420px) {
7  .card { ... }
8}

正确做法是容器和查询目标分成两层:外层当容器,内层写查询。

04现在怎么用才稳

  • 容器单独包一层 div,别和业务元素混用,避免 containment 副作用。
  • 永远写 container-name,匿名容器在嵌套时会查错人。
  • 宽度单位用 cqi,比百分比更好推理。

下一篇不写技术,写点表达:技术分享的开场三十秒怎么设计。