CSS 嵌套放宽语法更新

Chrome 120 中启用了预测嵌套。

Adam Argyle
Adam Argyle

今年早些时候,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 属性和值。

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