Universal Selector * and Pseudo Elements

Universal selector * and pseudo elements

No, the universal selector * does not affect pseudo-elements (except indirectly via inheritance, as pseudo-elements are typically generated as children of actual elements).

The universal selector, like other named element selectors such as p and div, is a simple selector:

A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.

A simple selector, and by extension any complex selector, targets only actual elements.

Although pseudo-elements (which are not the same thing as pseudo-classes mentioned above) can appear in selector notation alongside simple selectors, pseudo-elements are completely separate from simple selectors as they represent abstractions of the DOM that are separate from actual elements, and therefore both represent different things. You cannot match a pseudo-element using a simple selector, nor can you apply styles to an actual element in a CSS rule with a pseudo-element in its selector.

So, in order to match :before and :after pseudo-elements of any element, yes, one will need to include *:before, *:after in the selector. Having just * { box-sizing: border-box; } will not affect them since box-sizing is not normally inherited, and as a result, they will retain the default box-sizing: content-box.

One possible reason why you might never have had any issues with pseudo-elements is that they're displayed inline by default, as box-sizing has no effect on inline elements whatsoever.

Some notes:

  • As with any other chain of simple selectors, if * is not the only component then you can leave it out, which means *, :before, :after is equivalent to *, *:before, *:after. That being said, the * is usually included for the sake of clarity — most authors are used to leaving the * out when writing ID and class selectors, but not pseudo-classes and pseudo-elements, so the notation may seem strange and even wrong to them (when it is in fact perfectly valid).

  • The current Selectors specification that I link to above represents pseudo-elements with double colons. This is a new notation introduced in the current spec to distinguish pseudo-elements from pseudo-classes, but most box-sizing resets use the single colon notation to accommodate IE8, which supports box-sizing but not the double colon notation.

  • Although *:before, *:after applies styles to the respective pseudo-elements of any element, which includes html, head and body, the pseudo-elements will not actually be generated until you apply the content property. You do not have to worry about any performance issues as there are none. For a detailed explanation, see my answer to this related question.

Do CSS combinators add specificity to a CSS selector?

The problem in your snippet is that you have two selectors(div > p) in the 1st rule and in the 2nd rule only one selector(p), therefore the 1st rule is more specific, so the article is correct.

See the snippet below using the same 2 selectors, but the 1st having a combinator >, as they have the same specificity the latter will apply due to cascading.

div > p {  color: red;}
div p { color: green;}
<div>  <p>First Paragraph</p>  <p>Second Paragraph</p></div>

Does the :not pseudo class increase the specificity of a selector?

Yes, it adds the specificity of its argument. Look at the first sentence:

The specificity of the :not pseudo class is the specificity of its argument. The :not() pseudo class does not add to the selector specificity, unlike other pseudo-classes.

So the specificity of .red:not(.blue) is equal to that of .red.blue — 2 class selectors, or (0, 2, 0), making it more specific than .red on its own. What the second sentence means is that the :not() itself does not contribute the additional specificity of a pseudo-class to make it (0, 3, 0), like the :hover in .red.blue:hover does for example.

Why use * selector in combination with *::before and *::after

See these two JSFiddles:

http://jsfiddle.net/86gc1w6f/
http://jsfiddle.net/gwbp2vpL/1/

Or try these snippets:

CSS:

* {
box-sizing: content-box;
}

p {
position: relative;
width: 200px;
border: 10px solid rgba(255, 0, 0, 0.5);
}

p::after {
position: absolute;
right: -100px;
top: -10px;
width: 100px;
height: 30px;
border: 10px solid rgba(0, 0, 255, 0.5);
content: '';
}

HTML:

<p>
A paragraph
</p>

Changing the box-sizing between content-box and border-box only alters the size of the paragraph, not it's ::after element. As others have noted, this is because they are, as named, pseudo elements and must be targeted separately.

It would appear that * does not target psuedo-elements (which as @Harry points out, is as per the CSS specification)

Why does hover pseudo-selector on universal/wildcard selector seem to not apply?

Credit goes to @TemaniAfif for this (see comments in the question).

The answer is that you need to declare a doctype at the top of the HTML file. Without it, various browsers will render the page in "quirks mode" which allows backwards compatibility with older websites.

Select all pseudo elements and classes

* selects any element regardless of its nature or state. In this way, it already covers all pseudo-classes, just with zero specificity.

For example, * will match any element regardless of whether it is :first-child, :last-child, or both (which itself can be expressed using either :only-child or :first-child:last-child). It will also match any link whether it is unvisited (:link) or visited (:visited), and whether or not it matches one or more of :hover/:active/:focus.

If you're looking for a way to override any and all CSS rules with pseudo-classes for a given element (which can be useful in the case of dynamic pseudo-classes such as the one for links), the only ways are to use an ID selector, an inline style attribute, or !important.

* doesn't match pseudo-elements because it is a simple selector, and a simple selector only matches actual elements. See my answer to this question for a detailed explanation.

The likely reason that there isn't a selector for matching all pseudo-elements is because it doesn't make sense to have one, since different pseudo-elements work differently and have different restrictions as to which CSS properties may be applied to them. For example, content and display don't apply to ::first-letter, ::first-line or ::selection. But the universal selector exists because elements themselves don't define what CSS properties are applicable (not usually, anyway); as far as CSS is concerned, every element is more or less equal.



Related Topics



Leave a reply



Submit