Is Box Sizing Inherited If Declared Inside Universal Selector

Why inherit the box sizing css reset than apply it directly to all elements?

What

html {
box-sizing: border-box;
}

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

is saying is that html element has box-sizing: border-box and that all elements are then going to inherit the box-sizing of their parent.

So, if you like 'to begin with' every element inherits box-sizing from html's setting because no one has told it anything different.

But supposing you have somewhere

.mydiv {
box-sizing: content-box;
}

with HTML

<div class="mydiv">
<header>some text...
</header>
</div>

what do you expect the box-sizing of the header element to be?

What setting the inherits above is saying is 'I expect header to inherit its box-sizing from its parent' and that is content-box.

If we'd had everything set to border-box at the start it would not be inheriting, it would use what it had been set at, border-box.

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)

What's the purpose of these CSS rules?

This snippet has a few purposes, mostly just overriding/resetting some default styling. The * selector applies these values to every element on the page, and the ::before/::after make sure it also applies to any pseudo-elements.

Specifically...

  1. It removes all padding and margin from elements that have them applied by default. For example, <ul> elements:

<ul><li>I have a margin</li></ul>

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.

Why does a class property not override the Universal Property?

You're bumping into the crux of cascading, and the reason a lot of people avoid the wildcard selector.

The wildcard selector applies to all objects, and it isn't applying the style as an inheritance. You may assume that *{} is really affecting the <html> or <body> elements, but in actually it is applying directly to all elements. Because of this, *{} has higher specificity than an inherited style from the element's parent.

.table-dark is a container class, because of this, you likely have <tbody>, <tr>, and <td> elements between it and the content. This is stopping the <table> element from passing its font on. Think of it like this:

body {
font-family: helvetica;
}
table {
font-family: arial;
}
<body> <!-- helvetica -->
<div> <!-- inherited helvetica -->
<table> <!-- arial -->
<tbody> <!-- inherited arial -->
<tr> <!-- inherited arial -->
<td> <!-- inherited arial -->
content <!-- inherited arial -->
</td>
</tr>
</tbody>
</table>
</div>
</body>

Purpose of *:before, *:after rule without content property

That applies border-box sizing to all elements as well as any :before and :after pseudo-elements that they may generate. The *:before, *:after portion means the respective pseudo-elements of any element.

Once you create specific :before/:after rules later in your stylesheet, this declaration will apply automatically to all of those pseudo-elements, so you don't have to repeat it in every single one of your pseudo-element rules. In other words, the cascade works exactly the same way for pseudo-elements as it does with actual elements: when you have separate rules matching the same thing, as long as they match, they will all be applied.

Note that in order for an element to actually generate a :before or :after, its content must be something other than none. By itself, the CSS that you have given will not cause every element to automatically generate both pseudo-elements; it just ensures the browser will use border-box sizing if it does need to render any of them. See the spec for how generated content works.

For example, the following CSS:

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

div:after {
content: "hello";
}

results in a div's :after pseudo-element having border-box sizing. No other elements generate :after pseudo-elements, but should more CSS rules be introduced they will all have the same box-sizing from the universal rule.

Note also that box-sizing: border-box without the -moz- prefix should appear in the given CSS so other browsers will apply the same box sizing as well. The -moz- prefix is used by Firefox up to version 28 (the just-released version 29 ships with unprefixed box-sizing). See this answer.

using the * selector in css, but exclude h1?

Well, quick answer is replace * for *:not(h1).

This looks like a simple attempt of a normalize. You could remove it and fix whatever is wrong on plugin's elements or simply fix your h1 to have the margin/padding it was supposed to have.



Related Topics



Leave a reply



Submit