52

I'm trying to find some simple client-side performance tweaks in a page that receives millions of monthly page views. One concern that I have is the use of the CSS universal selector (*).

As an example, consider a very simple HTML document like the following:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Example</title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }
  </head>
  <body>
    <h1>This is a heading</h1>
    <p>This is a paragraph of text.</p>
  </body>
</html>

The universal selector will apply the above declaration to the body, h1 and p elements, since those are the only ones in the document.

In general, would I see better performance from a rule such as:

body, h1, p {
  margin: 0;
  padding: 0;
}

Or would this have exactly the same net effect?

Does the universal selector perform more work that I may not be aware of?

I realize that the performance impact in this example may be very small, but I'm hoping to learn something that may lead to more significant performance improvements in real-world situations.

I don't intend to override the styles in the universal selector rule with other styles later in the document - i.e., using it as a quick and dirty reset stylesheet. I'm actually trying to use the universal selector exactly as I think it's intended - to apply a rule set to all elements in the document, once and for all.

Ultimately, I'm hoping to determine if there is something inherently slow about the universal selector, or if it just has a bad rap due to rampant misuse. If * { margin: 0; } is literally equivalent to body, h1, p { margin: 0; }, then that will answer my question, and I'll know to go with the former since it's more concise. If not, I want to understand why the universal selector performs more slowly.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Bungle
  • 19,392
  • 24
  • 79
  • 106
  • 3
    From a performance viewpoint, when is it _ever_ better to globally disable (or enable) a characteristic for _everything_ only to eventually re-set it? Learning browser defaults will not take you long — you can get hints from "reset" CSS files, but I wouldn't go so far as to actually use one. Open source browsers have open source CSS defaults you can look at. – reisio Jun 01 '10 at 18:03
  • I'm not sure that you've understood my question. I'm not looking to reset and then reapply styles here, but rather apply a rule to every element on the page. My question is whether it's technically the same to use the universal selector as it is to select each element individually, or if either incurs a performance penalty for any reason. – Bungle Jun 01 '10 at 23:06
  • `*` is not literally equivalent to `body, h1, p` for obvious reasons. The *only* reason why it performs more slowly is because you apply styles to everything, whereas any other selectors limit you to a specific subset of elements in the DOM. But the real question is, is it that much slower that a browser will become unresponsive from applying too many styles? I highly doubt it. See also: [* { box-sizing: border-box } FTW](http://paulirish.com/2012/box-sizing-border-box-ftw) – BoltClock Jul 23 '12 at 08:08

3 Answers3

80

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

mxcl
  • 26,392
  • 12
  • 99
  • 98
3

I understand that wildcards have a performance impact, but on smaller sites the impact is negligible. Wildcards are very useful tools for building a site based on progressive enhancement. Obviously, using something like HTML *, really impacts performance on larger sites, but making it more specific, such as #element_id *, helps to quickly make universal changes to child elements.

The wildcard is there for a reason after all. You just have to understand when using it will be more beneficial than not using it. It depends on the context.

I use wildcards and generic selectors when making CSS templates. It's also a great way of quickly tweaking a range of elements inside an unfamiliar WordPress theme using custom styles.

Even Bootstrap, which is popular and streamlined, uses wildcards under the right circumstances.

References:

  • http://getbootstrap.com/css/
  • Gustafson, A. 2015. Adaptive Web Design: Crafting Rich Experiences with Progressive Enhancement. Berkeley, (CA): New Riders.
0

Avoiding generic selectors will always speed up your page rendering. The wildcard * is slow, especially when your pages become complex nests and your element counts skyrocket.

You should always specify an ID down to the lowest level that you possibly can (I realize that this becomes near impossible especially when dealing with things like database results). But when you use selectors like

.mysuperclass ul li p a

You have a class followed by four generic selectors - that means that for each element of .mysuperclass the rendering engine has to loop through every element in that parent looking for these rules.

In short, my answer is to be as specific as possible with your CSS, and drill down as far as you can into the DOM with your selectors. Avoid wildcards and generics.

Jarrod Nettles
  • 6,193
  • 6
  • 28
  • 46
  • Thanks, Jarrod. I think I could have better emphasized in my question that I do want to target every element on the page with my CSS rule(s) - i.e., the universal selector, as I understand it, is exactly what I want in this case. Since I've also always heard the universal selector to be slow, I'm hoping to learn if that slowness is inherent to the selector, or is just based on its typical usage (e.g., a quick and dirty reset stylesheet that will be followed by styling overrides). – Bungle Jun 01 '10 at 23:16
  • I see. I would suggest doing some speed tests using Chrome's developer tools. Test it out and see the results for using the wildcard selector versus explicit tag definition. Chrome will give you a breakdown of how long each process takes. – Jarrod Nettles Jun 02 '10 at 04:13
  • 18
    I would advise *against* being "as specific as possible" with your selectors. In the future when you want to make changes to styles or when you have more exceptions, you'll want to override those selectors, which becomes increasingly harder the more specific they are. Keep specificity low, and use more element and class selectors. http://numiko.com/labs/2011/07/css-specificity-wars/ – chharvey Jan 24 '14 at 06:33
  • Absolutely agree with chharvey, greater specificity = greater bloat + greater effort to maintain & extend. My general rule is to never use more than 2 levels of nested rules. This is absolutely achievable even on large projects, especially when using a methodology like BEM (http://getbem.com/) – Mike Aug 01 '16 at 09:37
  • This is horrible "advice". It's VERY slow when every nesting element must be searched for. You use .mysuperclass a and that's it. – Jiulin Teng May 09 '21 at 06:37