Is the CSS Star Selector Considered Harmful (And Why)

Is the CSS star selector considered harmful (and why)?

When it comes to performance, Steve Souders is the man:

  • Performance Impact of CSS Selectors
  • Simplifying CSS Selectors

Shameless quote from one of the reports:

The key to optimizing CSS selectors is
to focus on the rightmost selector,
also called the key selector
(coincidence?). Here’s a much more
expensive selector: A.class0007 * {}.
Although this selector might look
simpler, it’s more expensive for the
browser to match. Because the browser
moves right to left
, it starts by
checking all the elements that match
the key selector, “*“. This means the
browser must try to match this
selector against all elements in the
page.

[bold emphasis mine]

What is the performance impact of the universal selector?

In modern browsers the performance impact is negligible, provided you don’t apply slow-effects to every element (eg. box-shadow, z-axis rotation). The myth that the universal-selector is slow is a hangover from ten years ago when it was slow.

Reference: http://www.kendoui.com/blogs/teamblog/posts/12-09-28/css_tip_star_selector_not_that_bad.aspx

Difference between universal and descending selector in CSS

The general rule is to use the universal selector very sparsely due to its bad impact on performance. You basically almost never use it.

The descendant selector, as the name suggests, targets descendants of the element preceding the descendant selector.

Please note that both selectors you show are not exactly the same.

It helps alot to read selector from right to left:

div * .test targets

  • items that have a css class test (.test)
  • which are descendants
  • of any element *
  • which is a descendant
  • of a div element.

See this example:

div * .test{
color: red;
}
<div>
<div class="test">test</div>
</div>

CSS Universal selector (*) specificity

The universal selector (*) has no effect on specifity, therefore the latter selector's styles will be the ones that are applied.

An asterisk (*) is the universal selector for CSS. It matches a single
element of any type. Omitting the asterisk with simple selectors has
the same effect. For instance, *.warning and .warning are considered
equal.

Is element-specific CSS selector bad?

.error is more efficient than p.error .

To understand why this is more efficient I recommend you read this article over at css tricks.

CSS Specificity and Inheritance

The .container rule doesn't match the p element. So specificity is irrelevant here. Inheritance and specificity are separate concepts and the only time they interact is when more specific/less specific rules contain declarations with inherit. That is not the case here.

As far as the p element is concerned, only the * rule applies, and the * contains its own font-size declaration, and so the specified font size follows that declaration.

If the * rule didn't have its own font-size declaration, then the p element would inherit from .container.

If you want descendants of .container to take after its font size, you will need an additional .container * rule. Be very careful with the inherit keyword when it comes to relative values, though — you probably meant to keep all descendants the same size, so 1em or 100% is more appropriate here than inherit:

* {  font-size: 18px;}
.container { font-size: 50%;}
.container * { font-size: 1em;}
<div class="container">  <p>    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate explicabo fugiat laborum minus ullam? Amet delectus facilis id quam temporibus.  </p></div>

CSS selectors Descendant selectors

To answer your question, you need to first understand how CSS rules are interpreted by the browser.

Whenever you write a CSS selector, you can use one or many elements in the selector. For instance, the selector div has one element, both div p and div > p have two.

Think of a CSS selector as several stages of filtering. CSS selectors are actually interpreted by the browser reading them from right to left. When multiple elements are specified in a selector, you first find the set all the elements for the right-most piece, then filter that set by the next piece, and so on.

In the case of the div rule, we are saying "find me all 'div' elements on the page". Simple enough.

In the case of the div p rule, we first "find all the 'p' elements on the page". But then, for each of those 'p' elements, we then ask "give me just the 'p' elements that have a 'div' as an ancestor".

Using the same logic, let's describe div * p: we first "find all the 'p' elements on the page". Next, we ask "give me just the 'p' elements that have a parent element of any kind". From that set, we then ask 'give me just the elements out of this set that have a 'div' as an ancestor".

The selector div * p would be almost the same as div p, but with one key difference: the <div> would have to be at least a grandparent of the <p> for the selector to match. See http://jsfiddle.net/cDTGY/ for an example.



Related Topics



Leave a reply



Submit