CSS 嵌套放宽语法更新

Chrome 120 中启用了预测嵌套。

今年早些时候,Chrome 在 112 版中发布了 CSS 嵌套功能,现在,所有主流浏览器都支持该功能。

浏览器支持

  • Chrome:120。
  • Edge:120。
  • Firefox:117.
  • Safari:17.2。

来源

不过,语法有一个严格且可能出乎意料的要求,无效嵌套示例的第一篇文章中列出了该要求。这篇后续文章将介绍规范和 Chrome 120 中的变化。

嵌套元素标记名称

CSS 嵌套语法首个版本最令人惊讶的限制之一是无法嵌套裸元素标记名称。此限制已被移除,因此以下 CSS 嵌套有效:

.card {
  h1 {
    /* this is now valid! */
  }
}

/* the same as */
.card {
  & h1 {
    /* this is now valid! */
  }
}

当嵌套有序列表、无序列表或定义列表时,这种方法会非常有用:

dl {
  dt {
    /* dl dt styles */
  }

  dd {
    /* dl dd styles */
  }
}

是什么变化让这种嵌套成为可能的?

这在很大程度上得益于 Chrome 工程师进行了一些探索和原型设计,以及社区和 CSS 工作组的期望。

我们对 CSS 解析器是否能够学会区分标记名称 (div) 和属性名称 (visibility) 存有相当大的疑虑,因为该解析器目前没有预测概念。为了了解令牌是属性,浏览器需要向前查看,看看未知令牌后面是否跟随 :。因此,在原始规范中,& 符号用于向浏览器指明后续内容是嵌套的,而不是常规的 CSS 属性和值。

幸运的是,一位工程师发现,当解析器无法按照正常的使用传递流程将嵌套选择器解析为属性时,可以采用假定选择器而非属性的模式来重启解析器。解析会继续,并将嵌套识别为选择器嵌套。该算法足够快速且可靠,因此我们认为其足以发布语法。