容器样式查询的早期

Avatar of Geoff Graham
Geoff Graham

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 $200 免费信用额度!

我们仍然处于容器查询的超级早期阶段。对于广泛的浏览器支持来说还为时过早,但 Chromium 已经支持它,Safari 从版本 16 开始支持它,而 Firefox 也可能 不会落后太多

大多数关于容器查询的早期讨论通常将语法与媒体查询进行比较。

/* Stacked flex container */
.post {
  display: flex;
  flex-direction: column;
}

/* Change direction when viewport is 600px or wider */
@media(min-width: 600px) {
  .post {
    flex-direction: row;
  }
}

/* Define the container */
.posts {
  container-name: posts;
  container-type: inline-size;
}

.post {
  display: flex;
  flex-direction: column;
}

/* Query the container's min-width */
@container posts (min-width: 600px) {
  /* Change styles when `posts` container is 600px or wider */
  .post {
    flex-direction: row;
  }
}

这两者都在查询 min-width: 600。区别在于媒体查询正在查看视窗的宽度以触发这些样式更改,而容器查询正在查看 .posts 元素的计算宽度。很棒!

但在听了 CSS Podcast 第 59 集 之后,Una 和 Adam 探讨了容器查询的未来:**样式查询**!CSS Containment Module Level 3 规范的当前工作草案 定义了容器样式查询

一个 容器样式查询 允许查询 计算值查询容器。它是一个布尔组合,其中包含各个 样式特征 (<style-feature>),每个特征都查询查询容器的单个特定属性。

但目前还没有语法示例 - 只有简短的描述

一个 <style-feature> 的语法与 声明 相同,如果查询容器上给定属性的计算值匹配给定值(该值也相对于查询容器进行计算),则该查询为真,如果属性或其值无效或不受支持,则该查询为未知,否则该查询为假。布尔语法和将 样式特征 组合成一个 样式查询 的逻辑与 CSS 特性查询 相同。(参见 @supports。)

因此,随着时间的推移,我们应该期待实现类似这样的功能

.posts {
  container-name: posts;
}

@container posts (background-color: #f8a100) {
  /* Change styles when `posts` container has an orange background */
  .post {
    color: #fff;
  }
}

这是一个相当愚蠢的例子。需要注意的是,container-type 不再基于容器的 inline-size,而是由 style 决定。我们可以像这样声明它

.posts {
  container-name: posts;
  container-type: style; /* unnecessary */
}

…但 所有容器查询默认情况下都是 style 查询。好吧。至少现在看来是这样的。Miriam Suzanne 有一个很好的 可能出现的问题概述

在哪些情况下查询容器的样式会派上用场?我目前还不知道!但我的思绪飞到了几个地方

  • **自定义属性值:**我们已经看到自定义属性像状态指示器一样使用,例如 Ana 之前介绍的 DRY-切换方法。值发生变化,样式也会发生变化。
  • **替代黑暗模式方法:**与其基于更改主体类来重新分配自定义属性值,不如在主体背景颜色发生变化时更改整个调色板。
  • **更复杂的查询条件:**例如,我们希望在容器的 sizestyle 条件都满足时应用样式。

Una 在 CSS Podcast 中还提到,容器样式查询可以帮助防止一些尴尬的样式情况,例如,如果我们碰巧在一个已经用斜体显示的 blockquote 中包含斜体文本。

blockquote {
  container-name: quote;
}

@container quote (font-style: italic) {
  em, i, q, address {
    font-style: normal;
  }
}