Writing efficient CSS selectors
csswizardry.com
csswizardry.com
Trying his tests on firefox 20 beta, shows no difference between id and class selectors (the article says there was minimal difference in ff6), also no difference between between the type and "heavily overqualified descendant" selectors (article reports a large difference) and the latter pair are approximately twice faster than the former (the article seems to report they were up to 40 times slower).
So beware that browser technology has progressed since the time of this writing. Of course once again you should be checking the behavior of your site with the browsers your users are actually using.
[Edit: originally confused the two pairs of tests in my browser tabs, the slow tests in ff6 are actually the faster tests in ff20]
Only the first paragraph should be red.
Removing the CSS from your example, and then using Javascript to change the color you see that only the first one is altered.
So, in terms of CSS, it doesn't really matter. Well, I don't know about performance issues with it though. But for Javascript it matters a great deal. As for HTML, it only really matters in that it's supposed to be unique for anchor targets, which would be one reason it doesn't validate.
Browsers give a great deal of leeway when it comes to HTML and CSS, because so many people and editors do not follow the spec. Of course, you could argue that no one follows the spec because the browsers don't really enforce it. I've been constantly amazed over the years seeing various examples of HTML soup that should not render in any recognizable form that somehow renders in the browser.
Although this is very interesting information, anyone reading this article should pay careful attention to the ending headline, "Is all this really necessary?" Odds are, unless you've produced some kind of CSS monstrosity, your CSS isn't the bottleneck in your website performance. Min and concat your Javascript, use appcache, local storage, etc. before prioritizing CSS performance.
> A lot of great information here.
Thanks!
> …unless you've produced some kind of CSS monstrosity, your CSS isn't the bottleneck in your website performance.
You’re definitely right insofar as selector efficiency should be last on your list of things-to-make-my-site-faster. CSS as a whole, however, is a pretty significant performance concern; I wrote a little more about that here: http://csswizardry.com/2013/01/front-end-performance-for-web... </plug>
Cheers! H
1) What if you ever need to use the selector on a different element? 2) A performance hit (though so slight it might as well not matter) 3) Increased specificity
I have written a lot about CSS selectors:
http://csswizardry.com/2012/05/keep-your-css-selectors-short... http://csswizardry.com/2012/07/quasi-qualified-css-selectors... http://csswizardry.com/2012/07/shoot-to-kill-css-selector-in...
H
http://calendar.perfplanet.com/2011/css-selector-performance...
CSS efficiency is a balancing act between best practices, speed, and maintainability. CSS rendering is really cheap compared to JavaScript or most other things, HTML excluded. So yeah, be aware of efficiency but don't let it come at the expense of maintainability. If you add a "non-semantic" class here or there so another developer can immediately understand what you're doing it's not going to be the end of the world and in fact is probably the right thing to do, efficiency be damned.
What I always try to do is identify patterns and use IDs and classes accordingly. So, for example, I've got an app that displays success and error messages based on input. I originally (and stupidly) gave each one its own class (i.e. '.user-signup-error' or '.save-file-error'). That wasn't going to scale. So I went back in and gave each type of design element it's own generic class. So now there are things like ".notification-box" and ".error-msg". All elements of that type will be notification-box'es and be given a default style then I'll have another class added to the same element indicating the type of message. IDs are real useful for giving JS something to hook onto but otherwise HTML5 has allowed us to now get rid of a lot of those #nav, #header, #sidebar IDs and instead just use the appropriate element name (nav, header, aside, footer, etc.) which is pretty cool.
All in all though, this is something to be aware of but not to worry too much about. Being too strict about efficiency can be just as bad as being overly inefficient.
[1]https://speakerdeck.com/csswizardry/breaking-good-habits-1
Selector and naming conventions can basically eliminate this problem. Module root elements have a class name that starts with a letter; module nested elements have a class name that starts with a dash. These are combined with the child selector to constrain their applicability.
What was once super-ambiguous, e.g.
body { color: black; }
.menu .item { color: orange; }
.menu .item .menu { color: black; }
.menu .item .menu .item { color: orange; }
/* and on */
is now very precise: body { color: black; }
.menu > .-item { color: orange; }
Is it the most efficiently interpreted ruleset? No, and I don't care. It's the most efficiently manageable ruleset. (Web Components will probably obviate this.)I always though that if I had:
#social a
The browser first get the social, then the "a" tag and analyze and store it in some DOM tree style information.
Edit: I found that it does work this way, and the reason is because browsers process content and apply CSS top to bottom as it renders, they do not first load all the content and then apply CSS rules.
From http://snook.ca/archives/html_and_css/css-parent-selectors
If you have a rule like body div#content p { color: #003366; } then for every element—as it gets rendered to the page—it'll first ask if it's a paragraph element. If it is, it'll work its way up the DOM and ask if it's a div with an ID of content. If it finds what it's looking for, it'll continue its way up the DOM until it reaches the body.
Obviously given the selector "div #foo a {}" (obviously a dumb selector, but...) it would be smarter to look for #foo and verify it was inside a div than get every div and search for a #foo. And by extension "div .foo a {}" (assuming .foo really is way more efficient than div, which again I find hard to believe given there's native support for getElementsByTagType).
It seems to me that the effectiveness of using classes probably stems from browsers optimizing against use cases like "OMG folks are using Dijit and hanging twelve classes off every div". There's no reason I can see why class selectors ought to be especially efficient, especially if -- say -- your markup has lots of classes and relatively few attributes (and isn't that more common these days?).
We should also probably differentiate between CSS selectors as affects page rendering and CSS selectors as affects grabbing a bag of nodes using jQuery $() or document.querySelectorAll().
Boris Zbarsky gives a good explanation of why here: http://stackoverflow.com/questions/5797014/why-do-browsers-m...
<ul id="social">
<li><a href="#" class="social-link twitter">Twitter</a></li>
<li><a href="#" class="social-link facebook">Facebook</a></li>
<li><a href="#" class="social-link dribble">Dribbble</a></li>
<li><a href="#" class="social-link gplus">Google+</a></li>
</ul>
could be written as: <a href="#" class="social-link twitter">Twitter</a>
<a href="#" class="social-link facebook">Facebook</a>
<a href="#" class="social-link dribble">Dribbble</a>
<a href="#" class="social-link gplus">Google+</a>
since you already have the social-link classes attached to it.Another example. This:
<div id="header"><h1>header</h1></div>
could be written as: <h1>header</h1>
since you should have only one H1 on your page.But to keep this on topic: my point is: a lot of time you can reduce your DOM.
Matt Cutts talking about this: http://www.youtube.com/watch?feature=player_embedded&v=G...!
Exact wording: Sections may contain headings of any rank, but authors are strongly encouraged to use headings of the appropriate rank for the section's nesting level.
http://www.w3.org/html/wg/drafts/html/master/sections.html#h...
I will keep an eye on this. Thanks for the pointer.
The final editor's response explains the reasoning: "Change removed advice recommending use of h1 elements as the utline algorithm has virtually no implementations and as a result use of h1 elements flattens document outlines for users who actually consume the heading semantics. While use of elements of the appropriate rank for the section's nesting level is backwards compatible"
<ul class="social-links">
<li><a href="#" class="twitter">Twitter</a></li>
<li><a href="#" class="facebook">Facebook</a></li>
<li><a href="#" class="dribble">Dribbble</a></li>
<li><a href="#" class="gplus">Google+</a></li>
</ul>
You would need to have a scary size document to reap the benefit of reducing your element nesting level by that little.Also if you don't want to commit to having a h1 as always being the header, using a class for the styling would be beneficial.
<h1 class="header">header</h1>
Or depending on your situation you might want to use a header tag.I'm not saying I totally agree, but OOCSS promotes the idea that your styles should be decoupled from your HTML structure. This makes CSS easier to maintain.
<a action="share">Share this article.</a>
Or better still, just have that as an option in the browser. Tada - 100% minimisation!
About this:
<div id="header"><h1>header</h1></div>
There are reasons to do this. If all your doing is simply wrapping a block element with a block element then that's likely not a good idea. You are right in that if any styling done to the div can be done to the h1 then you might as well skip using the div in the first place.One reason to do that is for a header with a defined size that has a background image for display and the h1 is text inside that header that can be placed via positioning. Although more than likely the h1 is not a good choice for that role.
https://developers.google.com/speed/docs/best-practices/rend... https://developer.mozilla.org/en-US/docs/CSS/Writing_Efficie...
Google https://developers.google.com/speed/docs/best-practices/rend...
Is using descendant selectors in that case bad enough to offset all those class attributes? I think I'd rather put a class on the ul or ol so that I can target the parents if needed and then can still easily target the li children.
I have got orders of magnitude faster sites by combining CSS or js files, gzipping content, adding cache control headers, serving via a cdn and not serving code that's not used.
I've also really benefitted from using logical markup and CSS selectors, not those designed for "efficiency" of the computer rendering them.