I was looking at the Twitter bootstrap framework and I do have a very small question.
I’ll see the following section in order to set the box-model to border-box
.
*, *::after, *::before { box-sizing: border-box; }
But if you look at the CSS specifications *
targets all elements, so why on earth is the *::after
and *::before
selector being used?
To me, this seems obsolete because the *
selector will already tag all elements.
7
Answers
::after and ::before are pseudo elements and they insert the style after or before the element correspondingly.
For your question with *::after and *::before is used to manage appearing spaces. If you don’t, the box-sizing is content-box and you’ll see the difference (even can’t see by our eyes) in spacing.
You can get more information about box-sizing here.
No. * selector will only select the real selector that are in DOM-Tree.
Here’s a picture I made for you using before and after pseudo element can insert element like this:
Pseudo elements are outside the DOM-Tree. So, using
*
won’t select them:You basically answered your own question.
::before
and::after
are pseudo-elements. The name even implies that they don’t represent true elements.The selector
*, *::before, *::after
is meant to match:*
All elements present in the DOM*::before
The pseudo element::before
relative to all elements present in the DOM*::after
The pseudo element::after
relative to all elements present in the DOMSince pseudo-elements aren’t qualified as full elements (
<html>
,<head>
,<body>
, etc.) and aren’t part of the DOM, they are not matched by an asterisk character. They are only matched when selected in reference to another element. They can’t be selected in JavaScript for the same reason. JavaScript only selects elements that it can find in the DOM, which is not true in reference to pseudo elements.To quote from MDN:
A simple selector is defined by W3C using the following definition:
Simple selectors are meant to match elements present in the DOM. A pseudo element must follow a simple selector since it is not part of the DOM itself, and consequently, can not be classified as an element. Since
*
is a simple selector, specifically the universal selector, pseudo elements in CSS can be chained to it to match all of that particular pseudo element type. Without the pseudo element selector, only a simple selector would remain (*
).Does * select all elements?
No,
*
does not cover pseudo-elements. They cover only real elements that are present in DOM.emphasis is mine
Why does property specified under * selector work for some but no others?
For some properties like
color
you would get the illusion of*
applying to all elements including pseudos because they are properties that a child can inherit from its parent.box-sizing
on the other hand is not an inherited property and hence must be explicitly mentioned on the pseudo elements also.Note: Though the pseudo-elements are named as
before
andafter
they are actually children of the element to which it is attached).Example to illustrate inheritance:
Have a look at the below snippet and see how the black
border
is applied only for the real elements. Among the pseudo elements, only thep:after
gets theborder
because it is directly specified on the pseudo-element itself. Thediv:after
gets no border.What are the list of inheritable properties?
You can find more details about the list of properties that a child can inherit from its parent here.
See these two JSFiddles:
http://jsfiddle.net/86gc1w6f/
http://jsfiddle.net/gwbp2vpL/1/
Or try these snippets:
CSS:
HTML:
Changing the box-sizing between
content-box
andborder-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)
*
targets all elements.::before
and::after
are pseudo elements so aren’t targeted by the*
so to target these as well you use the code you used in the OP.You can do a site without using pseudo elements at all it’s just there for the people that do use them so they have a consistant box-model and don’t start scratching their heads when they go to use a
::before
or::after
and it’s calculated differently.Below is the pseudo element structure from CSS-Tricks
*
will target only the element.*::after
and*::before
are pseudo elements, not real i.e they are not part of the DOM. They lie in between the content and element, so you could insert any extra content you wish without modifying the markup.The reason is
*::before and *::after
arepseudo-elements
. They are not indeed elements thats the reason they are calledpseudo
.They are not selected by
*
because it selects only elements. Thats why you cannot select them