CSS3 伪类与 SVG 可渲染元素的兼容性如何?

What is the compatibility of CSS3 pseudoclasses with SVG renderable elements?

我一直在学习 SVG 并遇到了 this informative article。作者指出

Most CSS selectors can be used to select SVG elements. In addition to the general type, class and ID selectors, SVGs can be styled using CSS2’s dynamic pseudo-classes (:hover, :active and :focus) and pseudo-classes (:first-child, :visited, :link and :lang. The remaining CSS2 pseudo-classes, including those having to do with generated content (such as ::before and ::after), are not part of the SVG language definition and, hence, have no effect on the style of SVGs.

这位作者在网络上有很多文章,显得很有学问。但是,"the remaining CSS2 pseudo-classes....have no effect on the style of SVGs" 语句让人对 CSS3 伪类感到疑惑。以我在 Codepen(FF 作为浏览器)上生成的这个例子为例。

<svg width="220" height="220" xmlns="http://www.w3.org/2000/svg">
    <rect x="10" y="10" width="100" height="100" />
    <rect x="110" y="110" width="100" height="100" />
</svg>

<style>
    svg { border: 3px dashed #999 }
    svg > rect:hover { fill: green }
    rect:nth-child(even) { fill:red }
</style>

CSS3 :nth-child 伪类在这里工作得很好(用红色填充第二个矩形)。另一个例子:用另一个 CSS3 伪类选择器替换上面的 :nth-child 规则,一个 :not 规则(所有其他仍然是相同):

rect:not([x="110"]) { fill:red } // fills the 1st rectangle red

我找到了 this reference 但它对我没有帮助。

CSS3 伪类与 SVG 元素的兼容性如何?

注意:我假设这些伪类规则仅适用于 SVG renderable elements

以下是 CSS3 Pseudo-class 选择器的完整列表,如 Selectors Level 3 Editor's Draft, where the ones with bolded 中定义的与 SVG 兼容:

这些在草案中有定义但没有语义:

  • :enabled
  • :disabled
  • :checked
  • :indeterminate

以上在 HTML5 Specification 中给出了含义,以及其他 pseudo-classes.

的一些其他定义

总而言之,似乎所有 CSS3 pseudo-classes 都有效,除了 :root。您可以在 MDN documentation for pseudo-classes 阅读更多内容。我找不到描述兼容性的可靠资源,所以这都是通过测试确定的。 CSS3.

中没有定义其他 pseudo-classes 或 pseudo-elements

这里有一个 pen,通过应用 fillstroke SVG 可渲染元素的属性。

我在两个不同的组中定义了不同的 SVG 元素(两个 parent 元素,在钢笔中显示为两列)以适应所有 pseudo-classes 即 select不同种类的 children:

<svg width="450" height="300">
  <g transform="translate(5,5)">
    <rect x="0" y="0" width="25" height="25" />
    <rect x="0" y="40" width="25" height="25" />
    <rect x="0" y="80" width="25" height="25" />
    <circle cx="15" cy="132" r="13.5"/>
    <circle cx="15" cy="170" r="13.5"/>
    <polygon points="2,200 28,200 14,225"/>
    <rect x="0" y="240" width="25" height="25" />
  </g>
  <g transform="translate(5,5)">
    <rect x="220" y="0" width="25" height="25" />
  </g>
  <g transform="translate(5,5)" font-family="Verdana" font-size="16" fill="#444">
    <text x="40" y="20" >:root</text>
    <text x="40" y="60">:nth-child(2)</text>
    <text x="40" y="100">:nth-of-type(3)</text>
    <text x="40" y="140">:first-of-type</text>
    <text x="40" y="180">:nth-last-of-type(1)</text>
    <text x="40" y="220">:only-of-type, :last-of-type</text>
    <text x="40" y="260">:nth-last-child(1), :last-child</text>
    <text x="260" y="20">:only-child, :last-child</text>
  </g>
</svg>

有趣的发现:

  • :root 似乎有效。正如预期的那样,它会应用于文档中的所有元素,包括 svg 元素。
  • 由于 :empty 应用于所有 void svg 元素,(<rect><circle><ellipse><polygon> 等) , 它很方便 selector 用于定位 SVG 形状元素。