CSS 选择样式的继承更改

Stephen Chenney
Stephen Chenney

发布日期:2024 年 10 月 8 日

从 Chrome 131 开始,::selection::target-text 伪类的 CSS 突出显示继承将发生变化。这是为了创建一个更直观的继承模型,并与最近添加的 ::highlight::spelling-error::grammar-error 伪类保持一致。本博文对此次变更进行了说明 会对大多数网站产生明显的影响。

所选项的样式设置

为所选文本设置样式可以向用户传达含义,例如所选内容的用途或无法选择文本。例如,GitHub 为所选代码采用与所选目录不同的颜色 结构。

CSS 支持使用 ::selection 伪元素,是一组伪元素之一,称为 突出显示伪元素。 这些伪元素可控制文本在不同用户、不同用户、 浏览器或脚本驱动的操作。除了选择之外,您还可以设置拼写错误 (::spelling-error)、语法错误 (::grammar-error)、嵌入网址的文本目标 (::target-text) 和脚本生成的突出显示内容 (::highlight) 的样式。

与任何 CSS 属性集一样,在设计网站时,继承行为是一项重要考虑因素。一般来说,开发者希望 可通过 DOM 元素树继承的属性(例如, font),或者完全不继承(例如 background)。

Chrome 131 中选择行为的变更

请考虑以下文档片段:

p {
  color: red;
}

.blue::selection {
  color: blue;
}
<p class="blue">Some <em>emphasized</em> text that one would expect to be blue</p>

fragment 的样式声明会修改所选文本的颜色,其中一个规则与所有元素匹配,另一个规则与类 "blue" 的元素匹配。在 Chrome 130 或更低版本中选择此项后,结果如下:

您认为应该为蓝色的文本为红色。

在 Chrome 131 中选择此选项后,结果会更改为:

文本现在以蓝色突出显示。

有哪些变化?选择属性的继承行为具有 历来都是通过原始元素继承实现的,其中 所选内容使用与该元素匹配的 ::selection 中的属性 所选对象。Chrome 130 及更早版本使用此模型,其中 强调文本没有匹配的 ::selection,因为 .blue::selection 仅匹配包含 "blue" 类的元素,而 <em> 元素缺少该类。

Chrome 131 支持新行为,即元素会继承 和家长的个人信息。在前面的示例中,<em> 元素没有 ::selection 匹配自身,因此它会继承 <p> 元素的选择颜色。这称为 CSS 突出显示继承,您可以在较低版本的 Chrome 中试用此功能,只需在 chrome://flags 中启用实验性 Web 平台功能即可。

依赖于不继承的选择属性的网站可能会看到所选文本的外观发生变化,但 bug 报告中的证据表明,这种行为的用例很少。

用于选择的 CSS 自定义属性仍然有效

许多网站通过使用 CSS 自定义属性来模拟 CSS 突出显示继承。自定义属性通过元素树继承,因此 “从父级继承”结果如下:

:root {
   --selection-color: lightgreen;
}

::selection {
  color: var(--selection-color);
}

.blue {
  --selection-color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text that is blue</p>

在 Chrome 130 和 131 中同时选择此选项时,会出现以下结果:

第一行为绿色,第二行为蓝色。

在这里,每个元素都会通过元素树继承 --selection-color 属性的某个值,并且在选择文本时会使用此颜色。元素 .blue 类及其后代在选中后会显示为蓝色,其他 这些元素显示为浅绿色许多网站都使用这种方法 推荐在 Stack Overflow 上咨询。

为了保持兼容性,CSS 突出显示继承模型指定 ::selection(以及其他 CSS 突出显示伪元素)会从其来源元素(应用于它们的元素)继承自定义属性值。使用此方法的网站应该不会受到 Chrome 131 中的更改影响。

系统会忽略在 ::selection 伪元素本身上定义的自定义属性,以避免出现竞争性的继承行为。您必须在元素本身上定义这些属性,然后在伪元素中引用它们。

适用于 ::selection 的通用选择器会停用突出显示继承

不使用 CSS 自定义属性的网站可能使用通用选择器来设置所选文字的颜色。例如,如下 CSS:

::selection /* = *::selection (universal) */ {
  color: lightgreen;
}

.blue::selection {
  color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text</p>

这是在 Chrome 130(及更低版本)和 Chrome 131 中都选择的结果 (及更高版本):

文本的第一行为绿色。第二个是蓝色,但强调的单词是绿色的。

CSS 突出显示继承不会导致第二个强调的文本继承 蓝色,因为通用选择器与 <em> 元素匹配 并应用通用突出显示颜色,即浅绿色。

为了获得 CSS 突出显示继承的优势,请更改通用选择器 以仅匹配根,其后代将继承该根:

:root::selection {
  color: lightgreen;
}

.blue::selection {
  color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text</p>

在 Chrome 131 中的结果如下所示:

第一行文字显示为绿色。第二行是蓝色的。

如果您的网站修改了选择颜色,但没有使用自定义属性,那么它 您可能有一个适用于 ::selection 伪的通用选择器。好消息是,您的网站不会因 Chrome 中的这项变更而中断,但您将无法获得突出显示继承带来的任何人体工学优势。

::target-text 样式也发生了变化

本文所述的所有行为和变更均适用于 ::target-text 伪元素,就像对待 ::selection 一样。多种应用的使用场景 单个网站上的目标文本样式非常有限,而且这项功能是全新的, 所以您的网站在::target-text行为上不太可能发生变化。

此次变更的原因是什么?

在开发其他突出显示伪元素时,CSS 工作组决定使用突出显示继承模型实现继承。这已经是 ::selection 伪元素规范中的方法,但浏览器并未实现它。非选择伪元素使用突出显示继承,其中伪元素的继承方式就像是属性一样。也就是说,元素会继承突出显示的内容 伪元素。

为了确保所有突出显示伪造的一致性,CSS 的工作原理 小组重申支持沿用 ::selection 的突出显示功能,以及 浏览器也在努力启动新行为,同时尽量避免 现有网站

试试看

以下 CodePen 演示了更改。欢迎在 Chrome 131 中试用。