Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have been learning SVG and came across this informative article. The author states that

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.

This author has many articles on the web and appears very knowledgeable. However, the statement "the remaining CSS2 pseudo-classes....have no effect on the style of SVGs" makes one wonder about CSS3 pseudoclasses. Take this example I generated on Codepen (FF as browser).

<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>

The CSS3 :nth-child pseudoclass works perfectly fine here (fills the 2nd rectangle red). Another example: substitute the :nth-child rule above with another CSS3 pseudoclass selector, a :not rule (all else remains the same):

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

I have found this reference but it does not help me.

What is the compatibility of CSS3 pseudoclasses with SVG elements?

Note: I am assuming these pseudoclass rules would only apply to SVG renderable elements.

like image 812
The One and Only ChemistryBlob Avatar asked Feb 14 '17 15:02

The One and Only ChemistryBlob


People also ask

Which pseudo-class can be used when styling SVG elements?

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.

What are CSS pseudo-classes and pseudo elements?

Pseudo-classes enable you to target an element when it's in a particular state, as if you had added a class for that state to the DOM. Pseudo-elements act as if you had added a whole new element to the DOM, and enable you to style that.

How do you add multiple pseudo elements in CSS?

Adding multiple pseudo elementsYou can combine several CSS pseudo-elements for one element. However, you cannot use CSS ::after two times or ::before two times. In the example below, the first letter of <div> is green and has x-large font size. The first line of <div> element is red and has small capital letters.

Can you combine pseudo selectors?

If you're talking about pseudo-classes, then yes, you can combine them in any order.


2 Answers

The following are the full list of CSS3 Pseudo-class Selectors as defined in Selectors Level 3 Editor's Draft, where the ones with bolded links ones are compatible with SVG:

  • :target, selects elements that are targeted via fragment identifiers
  • :root, selects the root of the document, which is the html tag, with higher specificity
  • :nth-child(an+b), selects element that has an+b-1 siblings before it in the document tree
  • :nth-of-type(an+b), selects element that has an+b-1 siblings before it with the same element name in the document tree
  • :nth-last-of-type(an+b), selects element that has an+b-1 siblings after it with the same element name in the document tree
  • :last-child, selects any element that is the last child of its parent
  • :first-of-type, selects the first sibling of its type of the parent's children
  • :last-of-type, selects the last sibling of its type of the parent's children
  • :only-child, selects element that has a parent element that has no other children
  • :only-of-type, selects element that has a parent element that has no other children with the same element name
  • :empty, selects element that has no children at all
  • :not(X), selects element that is not selected by selector X, which is a simple selector

These were defined but without semantic meaning in the draft:

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

The above are given meaning in the HTML5 Specification, along with a few other definitions for other pseudo-classes.

In summary, it seems like all CSS3 pseudo-classes work except for :root. You can read more at the MDN documentation for pseudo-classes. I could not find a credible resource describing the compatibility, so this was all determined through testing. There are no other pseudo-classes or pseudo-elements defined in CSS3.

like image 57
Andrew Li Avatar answered Oct 12 '22 13:10

Andrew Li


Here's a pen that demonstrates the application of the full list of CSS3 Pseudo-class Selectors (outlined by @andrewli) on SVGs by applying fill or stroke attributes to SVG renderable elements.

I defined the different SVG elements in two different groups (two parent elements, shown in the pen as two columns) in order to fit in all the pseudo-classes that select different kinds of 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>

Interesting findings:

  • :root does appear to work. As expected, it gets applied to all elements, including svg elements, in the document.
  • Since :empty gets applied to all void svg elements, (<rect>, <circle>, <ellipse>, <polygon>, etc), it's a handy selector for targeting SVG shape elements.
like image 40
gifteconomist Avatar answered Oct 12 '22 13:10

gifteconomist