user4779
user4779

Reputation: 817

Pseudo-class inheritance understanding

I thought that pseudo-classes inherited properties from their parent element, but in practice it seems the parent element specifically selects all its pseudo-classes, even if they're not specified.

Eg, given the HTML:

<a href="#" id="id-selector">ok</a>

and CSS:

#id-selector {
  color: green;
}

a:any-link {
  color: red;
}

I thought that color: green would only be inherited by the pseudo-class any-link, and thus be overriden by the a:any-link selector since this is a specific selector for the pseudo-class, and specific selectors override inherited properties even if they have a lower specificity. But the output of the above is a green link, indicating that #id-selector is specifically targeting any-link, not it being inherited.

An example of a specific selector with a lower specificity overriding an inherited property with a higher specificity:

HTML -

<div id="id-has-high-specificity">
    <h1 class="class-has-low-specificity">Heading</h1>
</div>

CSS -

.class-has-low-specificity {
  color: green;
}

#id-has-high-specificity {
  color: red !important;
}

here the output is green, which is expected, since the heading is only inheriting from the second rule, but is being specifically selected by the first rule.

I thought this same thing applied to pseudo-classes, in that pseudo-classes inherited from their parent element. But it seems from my first example that they don't, and that rather the parent element specifically selects all its pseudo-classes, even if they're not specified.

Is it the case then that pseudo-classes don't inherit any properties from their parent element, but instead the parent element specifically sets all of its pseudo-classes whenever a rule for it is defined, even if those pseudo-classes aren't specified?

Upvotes: 0

Views: 1111

Answers (1)

A Haworth
A Haworth

Reputation: 36426

CSS ascertains which selector(s) 'win(s)' following a set of order of precedence rules.

For example, from MDN:

Selector Types The following list of selector types increases by specificity:

  1. Type selectors (e.g., h1) and pseudo-elements (e.g., ::before).

  2. Class selectors (e.g., .example), attributes selectors (e.g., [type="radio"]) and pseudo-classes (e.g., :hover).

  3. ID selectors (e.g., #example).

So in the example given in the question:

<a href="#" id="id-selector">ok</a>
and CSS:

#id-selector {
  color: green;
}

a:any-link {
  color: red;
}

The color does not turn to red because the id selector takes precedence, even though the setting for a comes after in the 'cascade'.

Here's a snippet where the color does change (for this example on a hover):

#id-selector {
  color: green;
}

a#id-selector:hover {
  color: lime;
}

a:hover {
  color: red;
}
</style>
<a href="#" id="id-selector">ok</a>

UPDATE From comments I'm wondering if there is some confusion about pseudo elements (and classes) - they are 'part of' the one element, they are not a child of a 'parent' element.

This snippet has a parent/child and in that case the specificity as assumed in the question works:

#id-selector {
  color: green;
}

a:hover {
  color: red;
}
<div id="id-selector"><a href="#">ok</a></div>

Upvotes: 1

Related Questions