Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Universal selector * and pseudo elements

Tags:

Does the universal selector * affect pseudo elements like :before and :after?

Let me use an example:

When doing this:

* { box-sizing: border-box; } 

...doesn't the above declaration automatically include/affect pseudo elements like :before and :after as well?

Or, in order to affect pseudo elements like :before and :after, one has to declare this?

*, *:before, *:after { box-sizing: border-box; } 

Does this make sense?


I have always used just * { box-sizing: border-box; } and never have had any issues with pseudo elements whatsoever. But I see many tutorials doing *, *:before, *:after but they never really explain why they include *:before, *:after in the declaration.

like image 293
Ricardo Zea Avatar asked Jul 17 '14 03:07

Ricardo Zea


People also ask

What does the universal selector (*) Select?

Universal Selector in CSS is used to select all the elements on the HTML page. It is denoted by an asterisk (*).

What are pseudo-element selectors?

A CSS pseudo-element is a keyword added to a selector that lets you style a specific part of the selected element(s). For example, ::first-line can be used to change the font of the first line of a paragraph.

What is the difference between * and body selector?

What is the difference? body is an element selector (selects an element body ) while * is a universal selector (selects all elements).

What is the function of the universal selector asterisk (*) in this example?

The Universal Selector is the * in CSS. Literally the asterisk character. It is essentially a type selector that matches any type. Type meaning an HTML tag like <div> , <body> , <button> , or literally any of the others.


2 Answers

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.

like image 84
BoltClock Avatar answered Oct 13 '22 22:10

BoltClock


I can only cite from the specification:

The universal selector, written "*", matches the name of any element type. It matches any single element in the document tree.

Element types are for example span and div.

Since pseudo elements don't have an "element type" and are not part of the document tree, it looks like the answer is no, it does not include pseudo elements.

However, since pseudo elements inherit the CSS properties from their "parent" (at least the ones that are inheritable) and the universal selector also affects the parent, it indirectly affects the pseudo elements.

Example

  • the color is inherited
  • the border style is not and the ::before element doesn't have a border
like image 20
Felix Kling Avatar answered Oct 13 '22 20:10

Felix Kling