skip to Main Content

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.



  1. ::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.

    To me, this seems obsolete because the * selector will already tag all elements.

    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:

    enter image description here

    Pseudo elements are outside the DOM-Tree. So, using * won’t select them:

    enter image description here

    Login or Signup to reply.
  2. 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 DOM

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

    You can use only one pseudo-element in a selector. It must appear after the simple selectors in the statement.

    A simple selector is defined by W3C using the following definition:

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

    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 (*).

    Login or Signup to reply.
  3. Does * select all elements?

    No, * does not cover pseudo-elements. They cover only real elements that are present in DOM.

    From the W3C Spec:

    The universal selector, written as a CSS qualified name [CSS3NAMESPACE] with an asterisk (* U+002A) as the local name, represents the qualified name of any element type. It represents any single element in the document tree in any namespace (including those without a namespace) if no default namespace has been specified for selectors.

    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 and after 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 the p:after gets the border because it is directly specified on the pseudo-element itself. The div:after gets no border.

    * { /* selects all real elements */
      border: 1px solid black; /* not an inheritable property and so pseudos don't get it */
      padding: 10px;
      color: red; /* inheritable property and so pseudos which are children inherit it */
    div::after {
      content: 'abcd';
      margin: 4px;
    p::after {
      content: 'abcd';
      margin: 4px;
      border: 1px solid red;

    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.

    Login or Signup to reply.
  4. See these two JSFiddles:

    Or try these snippets:


    * {
        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: '';


        A paragraph

    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)

    Login or Signup to reply.
  5. * 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.

    Login or Signup to reply.
  6. Below is the pseudo element structure from CSS-Tricks

    Pseudo elements structure

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

    Login or Signup to reply.
  7. The reason is *::before and *::after are pseudo-elements. They are not indeed elements thats the reason they are called pseudo.

    They are not selected by * because it selects only elements. Thats why you cannot select them

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top