CSS
CSS容器查询目前在谷歌浏览器(105)中得到了支持,很快就会在Safari 16中得到支持。这对前端来说容器查询与媒体查询一样重要。
介绍一下容器查询是如何工作的,如何使用它们,以及语法是什么样子的,并分享一些现实生活中的例子和用例。

简介

在设计一个组件时,需要适配不同的变化,并根据CSS类或视口大小来改变它们。这对于开发来说不是很理想,只能根据变化类或视口尺寸来写CSS。
考虑下面例子:
CSS容器查询 - 图1
有一个卡片组件,当视口足够大时,它应该切换到水平样式。乍一看,这可能听起来不错。然而,当更深入地思考这个问题时,它就有点复杂了。
CSS容器查询 - 图2
如果想在不同的地方使用同一个卡片组件,比如在空间狭小的侧边栏和有更多空间的主区域,就需要使用不同的类来适配:

  1. .c-article {
  2. /* Default stacked style */
  3. }
  4. @media (min-width: 800px) {
  5. /* Horizontal style. */
  6. .c-article--horizontal {
  7. display: flex;
  8. align-items: center;
  9. }
  10. }

如果不想用上面的方式,那么会出现下面这样的情况:
CSS容器查询 - 图3
这种从用户界面的角度来看,并不友好。
通过容器查询,可以简单地编写响应父级或容器宽度的CSS。请看下图:
CSS容器查询 - 图4
注意到在媒体查询中,是如何根据视口或屏幕宽度来查询一个组件的。在容器查询中,同样的情况发生在父级上。

什么是容器查询?

通过 container-type 属性查询一个组件与最接近的父类的关系,该父类有一个定义的包含物。
过去在媒体查询中写CSS的方式,但只是针对组件层面。

容器查询语法

要根据一个组件的父级宽度查询,需要使用 container-type 属性。看下面的例子”

  1. .wrapper {
  2. container-type: inline-size;
  3. }

有了这些,就可以开始查询一个组件。在下面的例子中,如果.card元素的容器的宽度等于400px或更大,需要添加一个特定的样式。

  1. @container (min-width: 400px) {
  2. .card {
  3. display: flex;
  4. align-items: center;
  5. }
  6. }

虽然上述方法可行,但当有多个容器时,就会造成混乱。为了避免这种情况,最好为一个容器命名。

  1. .wrapper {
  2. container-type: inline-size;
  3. container-name: card;
  4. }

现在,可以在 @container 旁边加容器名称,如下所示。

  1. @container card (min-width: 400px) {
  2. .card {
  3. display: flex;
  4. align-items: center;
  5. }
  6. }

完整代码:

  1. .wrapper {
  2. container-type: inline-size;
  3. container-name: card;
  4. }
  5. .c-article {
  6. /* Default stacked style */
  7. }
  8. @container card (min-width: 400px) {
  9. /* Horizontal style. */
  10. .c-article {
  11. display: flex;
  12. align-items: center;
  13. }
  14. }

浏览器支持

容器查询现在在Chrome 105中得到支持,并很快在Safari 16中得到支持。
CSS容器查询 - 图5

事例

CSS容器查询 - 图6
这边有10个关于容器查询的事例,地址:https://lab.ishadeed.com/container-queries
来源:https://ishadeed.com/article/container-queries-are-finally-here/