A Shocking Truth about CSS

February 26, 2010
 

In which our heroes learn to their surprise that a fundamental assumption is wrong.

10:57:47 AM Alex M: omg
10:58:07 AM Alex M: I just learned something incredible about how css selectors are applied
10:59:29 AM Alex K: really
10:59:30 AM Alex K: what what
10:59:38 AM Alex M: yes!
10:59:40 AM Alex M: it’s changed my world
10:59:44 AM Alex M: you probably already know it
10:59:51 AM Alex M: it goes right to left
11:00:00 AM Alex M: for example: div div div div p {}
11:00:08 AM Alex M: first all p’s are gathered
11:00:18 AM Alex M: each p is analyzed for a div parent
11:00:40 AM Alex M: then the matched are again analyzed for the next left selector
11:00:49 AM Alex M: CRAZY!!
11:00:53 AM Alex M: did you know that!??!
11:01:13 AM Alex M: that is why the rightmost selector is called the key selector
11:01:24 AM Alex M: because it’s the most important key
11:02:02 AM Alex M: another example: #dogs div ul li {list-style:none}
11:02:14 AM Alex M: 1) all LIs on the page are gathered
11:02:35 AM Alex M: 2) All LIs are analyzed for a ul parent
11:02:46 AM Alex M: 3) those that matched are analyzed for a div parent
11:03:05 AM Alex M: 4) those that matched are analyzed for a #dogs parent
11:03:12 AM Alex M: then the style is applied
11:05:06 AM Alex M: This blows my mind
11:05:08 AM Alex M: changes my world
11:05:30 AM Alex K: woah
11:05:33 AM Alex K: that blows my mind too
11:05:35 AM Alex K: i had no idea
11:05:44 AM Alex K: that changes my whole set of assumptions
11:06:01 AM Alex K: doesn’t that mean that we should strive for as much specificity at the key selector level to speed up CSS processing?
11:06:04 AM Alex K: wow
11:06:12 AM Alex M: yes
11:06:14 AM Alex M: precisely!!!!
11:06:27 AM Alex M: which makes me think that manipulating LIs need to change
11:06:58 AM Alex M: whenever I manipulate LIs, for example, to be inline, I refer to them like “#inlineMenu li”
11:07:18 AM Alex M: instead each LI, for performance, should instead have .inlineMenu
11:07:30 AM Alex M: or #inlineMenu .menuItem
11:07:33 AM Alex M: something like that
11:07:42 AM Alex M: so that each .menuItem’s are gathered
11:11:10 AM Alex K: yeah
11:11:18 AM Alex K: that’s a really good point
11:11:41 AM Alex K: though that adds a ton of unnecessary DOM elements
11:11:48 AM Alex K: arg
11:12:12 AM Alex K: has anyone done speed measurement on CSS implementations?
11:12:36 AM Alex M: no unnecessary dom elements but additional classes
11:12:36 AM Alex K: sorry, that’s what i meant
11:12:51 AM Alex M: http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/
11:13:00 AM Alex M: this is the article that rocked my world
11:13:09 AM Alex M: he wrote the even faster web sites book
11:13:36 AM Alex M: and sometimes
11:13:45 AM Alex M: websites go crazy with css rules
11:13:52 AM Alex M: he reported in his blog
11:14:00 AM Alex M: that like facebook uses 2800 css rules
11:14:08 AM Alex M: for 1900 dom nodes!
11:14:56 AM Alex M: so in css 3, the worst thing you can do it #menuItem ul *
11:15:05 AM Alex M: because * gathers ALL elements!
11:15:09 AM Alex M: holy schnikes!
11:16:42 AM Alex K: i’m gonna read that
11:16:48 AM Alex K: wow
11:16:49 AM Alex K: crazy
11:17:03 AM Alex K: is this a CSS 3 change, or has it always been like that
11:17:19 AM Alex M: actually I think it’s been around
11:17:22 AM Alex K: so facebook uses 2800 css classes to address this problem?
11:17:30 AM Alex M: no no
11:17:33 AM Alex M: that’s a side note
11:17:44 AM Alex M: that’s a “why the hell do you have so many styles, facebook”
11:18:08 AM Alex M: that 1.5 css rules per DOM node
11:18:27 AM Alex M: it’d be bad if it were 1 css rule per dom node
11:18:32 AM Alex M: but 1.5 is ridiculous
11:19:12 AM Alex K: yeah
11:19:18 AM Alex K: though it might be to address that
11:19:29 AM Alex K: that is shocking
11:19:31 AM Alex K: and worrying
11:19:37 AM Alex M: google uses like 90 styles for 500 dom nodes
11:19:38 AM Alex K: i’m not sure i know how to apply this to writing CSS
11:19:43 AM Alex M: er…90 rules
11:19:43 AM Alex K: like how do you manage it
11:19:45 AM Alex K: where do you cut off?
11:19:54 AM Alex M: EFFICIENCY!
11:19:57 AM Alex M: it makes me really excited
11:20:07 AM Alex M: I need to redo the redo on the yoga website
11:20:11 AM Alex K: i guess in general, you want to avoid key selectors that are just elements without classes
11:20:13 AM Alex K: yeah
11:20:24 AM Alex K: beyond that, it’s probably too hard to manage properly?
11:20:34 AM Alex M: yeah and avoid any superfluous styles
11:20:42 AM Alex M: css is always manageable
11:20:46 AM Alex M: it’s not a beast
11:20:52 AM Alex M: it’s a domesticated companion
11:21:09 AM Alex M: so no ul#menuItem
11:21:15 AM Alex M: the ul in that case is superfluous
11:21:30 AM Alex M: since IDs are unique
11:21:34 AM Alex M: or are suppose to be unique
11:21:49 AM Alex M: best css practices with good semantic markup = an amazing site
11:22:01 AM Alex M: that is how we roll
11:22:14 AM Alex M: css is like a dog companion
11:22:28 AM Alex M: and html is like a more different dog companion
11:22:32 AM Alex M: javascript is like a cat
11:22:46 AM Alex M: it forces itself upon the dogs and does whatever it wants
11:23:01 AM Alex K: hahaha
11:23:09 AM Alex K: you should write a tech blog post about this!
11:23:18 AM Alex K: just a brief one saying how it totally changed your world view and link to the article
11:23:29 AM Alex K: brb
11:32:53 AM Alex K: i’m still trying to get my head around it
11:33:01 AM Alex K: we should write up a set of rules or something
11:33:07 AM Alex K: you seem to have a sense of what the implications are
11:33:28 AM Alex M: exactly
11:33:53 AM Alex K: and i don’t think i really do
11:33:53 AM Alex K: wow
11:34:00 AM Alex K: not every day your world is thrown in disarray
11:39:56 AM Alex M: http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/
11:40:09 AM Alex M: here’s the table of CSS rules to DOM elements
11:42:24 AM Alex K: wow, IE8 is FAST
11:44:19 AM Alex K: huh
11:44:33 AM Alex K: that makes it sound like it may not be worth huge optimization?
11:44:46 AM Alex M: no, not really
11:44:56 AM Alex M: I’m a purist though
11:45:18 AM Alex M: so this makes my world

10 Responses to “A Shocking Truth about CSS”

  1. You should watch this video: http://www.youtube.com/watch?v=a2_6bGNZ7bA (Faster HTML and CSS: Layout Engine Internals for Web Developers). It’s a great introduction to how browsers use CSS selectors and how they do the rendering of web pages.

  2. [...] full post on Hacker News If you enjoyed this article, please consider sharing it! Tagged with: ABOUT • [...]

  3. Awesome article. Gotta admit I love the conversational style. Nice job.

  4. While it’s great to be aware that this is the case, I think Steve’s final conclusion should be noted:

    “For most web sites, the possible performance gains from optimizing CSS selectors will be small, and are not worth the costs. ”

    http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/

  5. Yes, selectors are matched from right to left. But it works slightly differently than you described it here. Browsers DO NOT find DOM nodes for CSS selectors, it’s vice versa – for each DOM node browser finds matching selectors – and that explains why matching works from right to left.

    More on this:

    Writing Efficient CSS for use in the Mozilla UI
    https://developer.mozilla.org/en/Writing_Efficient_CSS

    Faster HTML and CSS: Layout Engine Internals for Web Developers
    http://www.youtube.com/watch?v=a2_6bGNZ7bA

  6. Hey everyone,

    Thanks for the comments! It’s very cool (and unexpected) to see this picked up.

    Learning that CSS is process from right-to-left was a fun surprise — all the astonishment of overturning a fundamental assumption without any of the pain of having to make changes. (Much as John points out.)

    Brad: thanks :) it worked out nicely. I wanted to write a blog post, so I just copied (nearly) word-for-word the gChat conversation I’d just had with my husband (M).

    Steve and Bruno: thanks for the links. The Mozilla site is very enlightening and concretely useful. Do either of you know if other browsers handle CSS processing in a similar fashion as described in the Mozilla link?

    I haven’t watched the video yet, but clearly we should.

    Cheers,

    Alex K

  7. [...] No mention of fractions: Web Standards for E-books Why fractions matter: Is Adobe Hindering eBooks? A Shocking Truth about CSS Getting New Users to Stick: Deconstructing how the best sites convert visitors to customers (Part 1 [...]

  8. [...] A CSS Revelation Just a reminder: CSS selectors are applied right to left. Two developers share a moment of revelation. See also the original post by Steve Souders: Simplifying CSS Selectors. [...]

  9. When I started researching performance of CSS selectors, I had heard horror stories of how they were responsible for bringing web pages to a crawl. As I dug into those specific test cases, it turned out it was a combination of bad CSS and bad JavaScript.

    As I focused on pure CSS selector performance, I found that for most sites this isn’t a high priority to fix. But certainly for some sites it is a problem. I’ll plug Page Speed here ( http://code.google.com/speed/page-speed/ ) because it has a rule that checks for inefficient CSS selectors and lists the worst offenders.

    Thanks for evangelizing this.

  10. You may have a look at the “match()” method in NWMatcher selector engine, it does exactly that, compiles CSS 3 selectors to pure “bottom-up” ad-hoc resolver functions. This is what makes so incredibly fast and specs compliant.

    I have setup a comparison between “internal” CSS selectors and frameworks/libraries selector engines here:

    http://dl.dropbox.com/u/598365/css3-compat/css3-compat.html

    the test was to measure consistency between the various implementation and frameworks actual browsers support and bug fixing capabilities. It looks like too much talk about speed instead of consistency.

    @steve, selectors are used in several ways, there are situation where the “match()” or equivalent method is going to be called several times per seconds as in event delegation, so selectors engines performance is key to faster UI interactions, though some kb more to download :-)

    Thank you for the good article.

Leave a Reply