CSS 容器查询

容器查询允许您根据元素容器的大小为元素应用样式。例如,如果容器在周围环境中可用空间较少,则可以隐藏某些元素或使用较小的字体。

容器查询是 媒体查询 的替代方案,媒体查询根据视窗大小或其他设备特征为元素应用样式。

Two different query types. First, a media query based on the viewport's width, which is the full width of the browser. Second, a container query based on the width of a container element.

使用容器查询

要使用容器查询,您需要在元素上声明一个 **包含上下文**,以便浏览器知道您可能希望稍后查询此容器的尺寸。为此,请使用 container-type 属性,其值为 sizeinline-sizenormal

这些值具有以下效果

size

查询将基于容器的 内联和块 尺寸。将布局、样式和大小 包含 应用于容器。

inline-size

查询将基于容器的 内联 尺寸。将布局、样式和内联大小包含应用于元素。

normal

该元素不是任何容器大小查询的查询容器,但仍然是容器样式查询的查询容器。

请考虑以下博客文章卡片组件的示例,该组件包含标题和一些文本

html
<div class="post">
  <div class="card">
    <h2>Card title</h2>
    <p>Card content</p>
  </div>
</div>

您可以使用 container-type 属性创建包含上下文

css
.post {
  container-type: inline-size;
}

接下来,使用 @container at-rule 定义一个容器查询。以下示例中的查询将根据最接近的包含上下文的祖先的大小为元素应用样式。具体来说,此查询将在容器宽度大于 700px 时为卡片标题应用更大的字体大小

css
/* Default heading styles for the card title */
.card h2 {
  font-size: 1em;
}

/* If the container is larger than 700px */
@container (min-width: 700px) {
  .card h2 {
    font-size: 2em;
  }
}

使用容器查询,卡片可以在页面的多个区域重复使用,而无需了解它每次将在哪里放置。如果包含卡片的容器宽度小于700px,卡片标题的字体将变小;如果卡片位于宽度大于700px的容器中,卡片标题的字体将变大。

有关容器查询语法的更多信息,请参阅@container页面。

命名包含上下文

在上一节中,容器查询根据具有包含上下文的最近祖先应用样式。可以使用container-name属性为包含上下文命名。命名后,可以在@container查询中使用该名称,以针对特定容器。以下示例创建了一个名为sidebar的包含上下文。

css
.post {
  container-type: inline-size;
  container-name: sidebar;
}

然后,可以使用@container规则来定位此包含上下文。

css
@container sidebar (min-width: 700px) {
  .card {
    font-size: 2em;
  }
}

有关命名包含上下文的更多信息,请参阅container-name页面。

容器语法简写

声明包含上下文的简写方法是使用container属性。

css
.post {
  container: sidebar / inline-size;
}

有关此属性的更多信息,请参阅container参考。

容器查询长度单位

使用容器查询将样式应用于容器时,可以使用容器查询长度单位。这些单位指定相对于查询容器尺寸的长度。使用相对于其容器的长度单位的组件在不同的容器中使用起来更加灵活,无需重新计算具体的长度值。

容器查询长度单位是:

  • cqw:查询容器宽度的1%
  • cqh:查询容器高度的1%
  • cqi:查询容器内联大小的1%
  • cqb:查询容器块大小的1%
  • cqmincqicqb中较小的值
  • cqmaxcqicqb中较大的值

以下示例使用cqi单位根据容器的内联大小设置标题的字体大小。

css
@container (min-width: 700px) {
  .card h2 {
    font-size: max(1.5em, 1.23em + 2cqi);
  }
}

有关这些单位的更多信息,请参阅容器查询长度单位参考。

容器查询的回退

对于尚不支持容器查询的浏览器,可以使用gridflex为本页面使用的卡片组件创建类似的效果。以下示例使用grid-template-columns声明为卡片组件创建两列布局。

css
.card {
  display: grid;
  grid-template-columns: 2fr 1fr;
}

如果希望为具有较小视口的设备使用单列布局,可以使用媒体查询更改网格模板。

css
@media (max-width: 700px) {
  .card {
    grid-template-columns: 1fr;
  }
}

另请参阅