Purpose of *:Before, *:After Rule Without Content Property

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.

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 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)

Can I use a :before or :after pseudo-element on an input field?

:after and :before are not supported in Internet Explorer 7 and under, on any elements.

It's also not meant to be used on replaced elements such as form elements (inputs) and image elements.

In other words it's impossible with pure CSS.

However if using jquery you can use

$(".mystyle").after("add your smiley here");

API docs on .after

To append your content with javascript. This will work across all browsers.

CSS :before and :after not working?

If you want :before and :after to work, you need to give them content, otherwise they don't really 'exist'. The easiest thing to do is, in the css, set content: '' for both pseudoelements.

CSS: How to remove pseudo elements (after, before,...)?

p:after {
content: none;
}

none is the official value to set the content, if specified, to nothing.

http://www.w3schools.com/cssref/pr_gen_content.asp

Can I have multiple :before pseudo-elements for the same element?

In CSS2.1, an element can only have at most one of any kind of pseudo-element at any time. (This means an element can have both a :before and an :after pseudo-element — it just cannot have more than one of each kind.)

As a result, when you have multiple :before rules matching the same element, they will all cascade and apply to a single :before pseudo-element, as with a normal element. In your example, the end result looks like this:

.circle.now:before {
content: "Now";
font-size: 19px;
color: black;
}

As you can see, only the content declaration that has highest precedence (as mentioned, the one that comes last) will take effect — the rest of the declarations are discarded, as is the case with any other CSS property.

This behavior is described in the Selectors section of CSS2.1:

Pseudo-elements behave just like real elements in CSS with the exceptions described below and elsewhere.

This implies that selectors with pseudo-elements work just like selectors for normal elements. It also means the cascade should work the same way. Strangely, CSS2.1 appears to be the only reference; neither css3-selectors nor css3-cascade mention this at all, and it remains to be seen whether it will be clarified in a future specification.

If an element can match more than one selector with the same pseudo-element, and you want all of them to apply somehow, you will need to create additional CSS rules with combined selectors so that you can specify exactly what the browser should do in those cases. I can't provide a complete example including the content property here, since it's not clear for instance whether the symbol or the text should come first. But the selector you need for this combined rule is either .circle.now:before or .now.circle:before — whichever selector you choose is personal preference as both selectors are equivalent, it's only the value of the content property that you will need to define yourself.

If you still need a concrete example, see my answer to this similar question.

The legacy css3-content specification contains a section on inserting multiple ::before and ::after pseudo-elements using a notation that's compatible with the CSS2.1 cascade, but note that that particular document is obsolete — it hasn't been updated since 2003, and no one has implemented that feature in the past decade. The good news is that the abandoned document is actively undergoing a rewrite in the guise of css-content-3 and css-pseudo-4. The bad news is that the multiple pseudo-elements feature is nowhere to be found in either specification, presumably owing, again, to lack of implementer interest.

Can the :before and :after pseudo-elements inherit height from the parent element?

No. The only way that pseudo-elements can inherit values from the parent of their generating element is when the generating element itself is also inheriting from its parent.

This is because inheritance occurs from a parent to a child, one level at a time. For inheritance to work across several levels of descendants, every descendant must inherit.

As an example, consider the following HTML:

<div class="parent">
<div class="child">
</div>
</div>

With the following CSS:

.parent {
width: 100px;
height: 100px;
}

.parent > .child:before, .parent > .child:after {
content: '';
position: absolute;
width: inherit;
height: inherit;
}

This will not work because even though the pseudo-elements have values of inherit, the element generating them, that is, .parent > .child, does not inherit from .parent. Instead, they inherit the default value of auto for both properties.

In order for this to work you will need to have .parent > .child inherit as well:

.parent {
width: 100px;
height: 100px;
}

.parent > .child {
width: inherit;
height: inherit;
}

.parent > .child:before, .parent > .child:after {
content: '';
position: absolute;
width: inherit;
height: inherit;
}


Related Topics



Leave a reply



Submit