Top 5 Mistakes of Massive CSS

Last week, Stoyan Stefanov and I spoke at Velocity Conference about optimizing massive CSS. We talked about our experiences optimizing large-scale sites like Facebook and Yahoo!, and we discussed our findings regarding the CSS efficiency of the Alexa Top 1000 websites.

Velocity was kind enough to share videos of the session:

What is the state of the internet regarding CSS performance? Kind of sad. We aren’t getting a lot of the basics right, and when we look at the more advanced techniques, there are some spectacular examples of what-not-to-do. Why do we care about CSS performance? As Stoyan talks about in the beginning of the video, it blocks progressive rendering and it is very difficult to auto-minify.

The Basics

These basic rules, made famous by YSlow, have been around for a long time, and yet our data showed that many sites in the Alexa Top 1000 are still not employing the most basic techniques.

  • 42% Don’t GZIP CSS
  • 44% Have more than 2 CSS external files
  • 56% Serve CSS with cookies (yummy to eat, bad for static content)
  • 62% Don’t minify (check out the YUI Compressor!)
  • 21% Have greater than 100K of CSS

CSS Weight for the Alexa Top 1000 Sites

More Advanced Techniques

I talked about these more advanced tests for the first time at Velocity. Here is how the top 1000 sites stack up and some recommendations for reasonable results.

Occurrences in one page
Declaration Max Percentage too many
> 10
Percentage sites *way* too many
> 100
Suggestion
float 733 56% 13% If you have a good nestable grids system, you shouldn’t need many floats. The worst offender in the Alexa Top 1000 sites declared the float property more than 700 times! Aim for less than 10.
h1-6 511 56% 9% There are only so many usable font sizes on the web. Below 10px in most fonts is legible only by mice and few sites use really large typography as a design element. Imagine that a site chooses to use 24px as their max. That leaves 14 different sizes, however, we need to divide that number by two because most users can’t see subtle differences like a 1px change in font size. That leaves seven different heading sizes, which means 56% of sites in the Alexa top 1000 have too many heading declarations.
margin: 0 518 64% 14% Different browsers have different default stylesheets. These stylesheets define how elements should look if you haven’t chosen an alternate style. It is important to get all browsers to the same starting point because it eliminates bugs and time wasted testing simple browser compatibility issues. This is should be accomplished using a reset stylesheet such as the one included in YUI. When a reset stylesheet isn’t used, margin zero tends to be sprinkled throughout the stylesheet as developers try to cope with browser differences in the absense of an abstracted solution. Setting the default margins to zero is the most basic job of a reset stylesheet, which means that 64% of the Alexa Top 1000 sites could benefit from including reset.css.
padding: 0 510 62% 10% Excessive declarations of padding zero are similar to margins (see the above description). The worse offender in this case declared padding zero 510 times.
font-size 889 78% 23% Headings (h1-6) often get hidden in class names, which can disguise typography efficiency issues. It is helpful to grep "font-size" to get an idea how many hidden headings exist on the site. The same rules apply to font-size that were explained under h1-6, so in fact the problem is much worse than our initial estimate. These figures mean that 78% of the Alexa Top 1000 sites have excessive heading declarations when we consider hidden headings. In addition, 22% of sites may not be getting the SEO benefits of properly using heading elements.
!important 526 - 12%* Important overrides all other declarations specificity, so it can be dangerous. If used correctly, only on leaf nodes, it can be a powerful tool for creating typography and spacing mixins that stand outside of the normal cascade. On the other hand, excessive use of important is a sure indication of specificity wars. Specificity wars are what happens when developers start trying to beat each others specificity, rather than having a real solid architecture and code standards. Eventually, like the worst offender in this case with 526 important properties, you can end up in a case where nearly every property is marked important. This means that 12% of the Alexa Top 1000 Sites probably has an internal specificity war in it’s web team.

* >50

Happy perf optimizing!

58 thoughts on “Top 5 Mistakes of Massive CSS”

  1. Great talk. :)

    I’m using those OOCSS concepts for quite a while for all new and side projects and it does indeed make sense to create rules which aren’t location specific. Less repetition and predictable results. I really like that.

    However, I recently started writing lots of documentation and I used HTML5′s section-tags there in conjunction with H1-tags (and no other headings at all). The big idea (borrowed from XHTML2) is to have some weighting for those headings based on the section nesting.

    It’s pretty handy since you can move things around like crazy and you’ll always get a heading with the correct weight. The same effect applies for things like aggregation or overview pages which display excerpts. You never really know where that markup will end up and if you only use section and h1, it will just work fine (at least that’s the theory):

    Now, the thing that apparently irks me, are those location specific styles. After all, this kind of thing can’t work without them.

  2. Can you explain the h1-6 one? Not sure I understand. Are we not supposed to use all of h1-6 and many sites do use all of them? Or are some sites using more than the 6 headings? *Confused*

  3. I’m at work and didn’t get to watch your attached video, so please excuse me if it is answered in there. :)

    Also, the rest of the rules are very helpful, thanks!

    1. @Bryan – definitely watch the video, I think it will make the whole thing clearer. And, check out the slides on slideshare. Basically, if there are only 7 workable font-sizes on a site, it makes no sense to have hundreds of font-size declarations and headings declarations. If we make ten or so that are reusable across the site, we shouldn’t need to keep repeating ourselves! The worst offender defined the heading sizes more than five hundred times and font-size almost 900 times! That’s just crazy. :)

  4. Well, I prefer the usage of inheritance instead of using classes for styling elements.
    In my opinion it’s better to use more classes for elements and IDs for single elements and it’s better to avoid traversing trees with classes – that’s stupid and uses more and more code to do the exactly same thing than the DOM does.

    e.g. the definition of:
    .abs { position:absolute; left:auto; right:auto; top:auto; bottom:auto; }
    .left { left:0px; }
    .right{ right:0px; }
    .top{ top:0px; }

    could be used in that way: …
    …and it’s more flexible =)

    PS: Have a look at the CSS at http://martens.ms

    Greets,
    Chris

  5. Well, I forgot to say:
    I also avoid using different CSS files for different pages. That’s also stupid – a user with a low bandwith has to look up the nameserver, download the file (if it has no ETags) and the browser has to differ the cache each time the page loads. It’s better to cache everything that will be used surely on the next pages. GZipping it is a good method for low-bandwith-users, but Opera doesn’t support gzipped Stylesheets (it’s a Bug in the cache handler)

  6. So it basically advertises one particular approach. Interesting metrics we have there: number of occurrences.
    How about number of classes after those “optimisations” are employed? How about that those classes will litter HTML too, and that’s worse cache-wise?
    I’d rather have zero id’s and classes in my HTML.
    Reset stylesheets and grids? God forbid.

  7. Nice piece. To clarify, in your CSS Weight data, are u using the post-gzip file size when enabled, or pre-gzip? And do you have a recommended target or suggested limit for total CSS weight per page in mind (pre or post gzip)?

  8. Pingback: alkaba222's me2DAY
  9. Wow, thank you for the video, it’s great

    I’m currently taking baby steps around the css/designing world, and trying some solutions to stop having terrible css designed. I’ll definitely give the framework a go

  10. Great video, nice to see chicks in this business ;)

    Just started with css, and while comparing stylesheets to learn from it, everytime i was like why the hack they use exactly the same stuff 4 lines down for exactly the same sort of objects (as you call it duplicates). Kinda mind goggling for a starter. Fun to see i wasn’t alone and there is actually a name for this more logical way of programming OOcss. I was wondering though you mentioned a google group, but i didn’t hear a name. mind telling me?

    Love to read your book when it comes out.
    cheers!

    William

  11. Ah I forgot to ask, so here I go; your talking about offenders of floats and that if you have a good grid system you shouldn’t see > 10 floats which sounds logical. Mind if I ask what grid system you could recommend. There are quite a few out there. :) And it might help newbies a bit in the right direction. If you have time of course =^.^=

  12. Hi Nicole, do you know of any big sites that are using your OOCSS in production right now? Sites that have some various page layout flavors? I watched the video and it is interesting, I’d really like to check some html/css of something more “real world” than “hello world” if you know what I mean. Or, do you have any in-depth demos like a fake site with various page layouts?

    Also, it doesn’t look like you’re using OOCSS on your blog, I checked the html/css file and it looks like “standard” type of markup. Not busting your chops, just want to make sure I’m looking at what I think I’m looking at.

  13. “Mind if I ask what grid system you could recommend.”
    I would love to know that too.
    I’ve tested quite a few, and always have some problems with them (not fluid, grid not usable inside a grid, problems with IE (IE6 but not only) etc.)

    1. @Jerome – would it be totally lame if I say my own grids? This is a link to the docs. When you’ve read that, you can click “source” and check out how I’ve implemented them. They allow infinite nesting and stacking, they’re flexible, and the file size is really small.

  14. Enjoyed the video and definitely came away some useful tips that I plan on implementing. I had some questions on a couple of points you made in the video.

    1. The ‘media’ block you created for Facebook – when I view my Facebook profile I do not see it in place – all I get is a infested block of HTML. Is this still in development or does it only appear on certain country sites (I’m in Canada)?

    2. The CSS reset you use (YUI) – any reason why you chose this over others (i.e. Eric Meyer’s)?

  15. Where can developers learn this information?

    I refer to the W3 as the definitive source for html and css. But I also have the following books, “CCS Definitive Guide”, “CSS Mastery”, “CSS in Easy Steps” (I love this little book – doesn’t waste your time), and “Transcending CSS”. I got the most out of the last 2 books for different reasons. But, on page 158, the author says, “For flexibility, I suggest you divide your CSS across three separate style sheets.” I’ve seen that in many places on the Net. The “mistake” of having more than 2 external CSS files doesn’t surprise me. I will definitely checkout “Best Practices for Speeding Up Your Web Site”.

    Could you name a couple of quality accessible resources that you believe could benefit developers, so the state of the Internet/CSS performance improves from “kind of sad”.

    Thank you.

  16. Theses stats takes me back when I was working at MySpace. About 2.5 years ago I was brought in to fix the most traffic pages at MySpace. The first thing that we did was applying most of the yahoo’s best practices. As mentioned on your article, most of our CSS problems were important declaration, font declarations and unnecessary floats. We took a huge step by dropping “everything” and creating a CSS system, where most of our developers would “never” have to style anything by just writing semantic markup and adding appropriate classes to elements. Anyways, It’s very refreshing to see someone else trying to fix the same issues that I we had and help the web.

    cheers.

  17. Do you have any examples of sites where Massive CSS (or not-so-massive css) is done right? Reading your stuff and checking out your slides has been enlightening since I have a medium sized site with a ton of distinct pages and a ton of CSS. Looking at some good CSS in practice would be really helpful.

  18. Hi Nicole,

    This was in interesting talk.

    Can you please clarify the benefits of using classes over IDs?

    Personally, I use this criteria

    - is this something that it would ever make sense to have more than 1 of on the one page?

    If not, I use IDs. So for example, the nav would always be an id. I can understand that it is good to use classes for reoccurring styles, this way you maximize reuse of the css across multiple elements. But if there is only ever going to be one per page, then there can be no reuse.

    I like to use IDs for the semantic meaning. IE. ‘This is one of a kind, a fundamental part of my site or a page’ vs ‘This is a generic component that can plug into multiple locations’.

    I also suspect that IDs are slightly faster..

    Would love to hear your thoughts.

    Cheers

  19. Hi Nicole,

    This was an interesting talk.

    I am curious about why you almost never use IDs.

    I personally use the following question to determine if I will use an ID or a Class.

    - Would it ever make sense to have more than one of these on a page? (even if there is only one now?)

    If I answer no I use an ID. So it would always be #nav.

    The specificity is also useful, because whilst it may inherit generic styling, I always want what I define for a unique item to override anything generic.

    I also like the semantic meaning. IE “This is one of a kind, a fundamental part of my page/site” as opposed to “This is a reusable doodad that could appear anywhere”.

    I also suspect there are (very minor) performance advantages to using IDs over classes.

    Why do you avoid them? How do you determine whether to use a class or an ID?

    Alistair

  20. I suspect that the reason behind overusing H1-H6 headings is because of the SEO implementation. That’s why you need to style headings that look differently depending on where they are. What’s your take on that?

  21. I watched this video, and the talk with Zeldman on the big web show, and even though there seems to be an idea behind the OOCSS approach, I don’t think it’s all so clear. (proof: all the questions above!)
    Most importantly, day after day, I realize there are SO many different approaches on best-practices regarding CSS development: Massive CSS, Location-dependent CSS, one css file – many small modular css files that aggregate, avoid ID’s completely – use them sparingly, etc…
    What I get from this presentation is that before starting to breakdown a design in HTML and CSS we need to do a good study -pencil and pen- of elements used throught the page – the similarities and differences, and how we can produce the less code possible.

  22. New web technologies are born daily and our responsibility as informed web service providers is to make good decisions about where to invest time and resources. The true value of web development should be measured by its positive return on investment instead of keeping up with the standards, UI and compatibility zeitgeist.

    Unless you are coding purely for pleasure there is a bottom line that must be met – commonly a mortgage payment or a client’s marketing budget. Long term web development success requires creating a system of best practices that balances your time and cost for professional development, project budgets, time lines and meeting 95%+ of your users’ system requirements.

    Constantly reinventing the wheel to take advantage of the latest and greatest CSS or HTML specifications is not a good strategy and it is very expensive. We talk about tables as if they were forged by the devil but over ten years of CSS layout advances many of the comments to this post were related to finding a high quality grid system!

    My takeaways from this very clear and concise presentation are:
    1. Take full advantage of the “cascade”. Use a reset.css to minimize unexpected behavior like margins that require massaging later burning unnecessary time and cost. Give all of your styles the same specificity to avoid unexpected conflicts.
    2. Universal rules (*) can be a great tool without using hacks.
    3. Remember to GZIP at the server level
    4. ID’s vs. Classes. It’s a valid argument to use element ID’s because of their primary key status in markup and use in JavaScript. Primary keys are essential to data architecture. I have employed the HTML ID technique for years but after watching this I will no longer apply my styles at the #id level and instead add reusable classes to achieve my basic layout settings removing a lot of redundancy. My new markup will look similar to this:

    Thanks for the tips and inspiration.

  23. @Nicole – Thanks for sharing.

    I completely understand why you’re advocating the removal of repetition in CSS rules, especially in light of the examples in your study. And you have definitely sparked an interest from me.

    But the techniques you propose seem to gain most benefit when tagging the HTML to suit the current site design (in addition to its semantic meaning). Have you had much resistance to this notion, or any problems with subsequence site redesigns or maintenance?

  24. Greetings, I have just watched your video and it really hit home how much my own CSS needs optimizing…thanks for the wake-up call.

  25. Nicole,

    I just want to say I really enjoyed the presentation. I do disagree with a few points, For example, you say never to use IDs for styling, but I do think there are times when it can be appropriate. I also see the need for some differences in headings under specific scenarios. If I have a two column layout with a heading at the top. Following the logical flow of the document, both should use the same heading level, but if I want to align the heading on the left column left and the right column right visually I will need a specific rule for this.

    Of course, this is where a clear plan comes into play. A simple scenario like this will result in one additional selector and one new property/value for that selector, this isn’t really that bad, but poor planning might result in new class rules on various places with this same situation happening, and dozens of new selectors/properties/values being added. Essentially using the style sheet to write inline styles. That is a terrible practice.

    This is where I see the biggest value for OOCSS. Instead of creating dozens of new rules, essentially defining an object that aligns heading to the right and itself floats to the right would allow for that object to be used throughout the site.

    In any case, having seen CSS used terribly in many places I am very happy to see some folks pushing for something better. This is likely to be difficult, but well worth it in the end, much like the standardization of tags that came with the progression of html. We need to see some standardization in CSS practices. Of course CSS will always be a bit more art than science, so the rules will be broken. Hopefully folks will learn the rules so they break them well, not sloppily like they do now.

  26. Hi Nicole, thanks for the great presentation. At almost 38 minutes, it is probably the longest video I ever watched on YouTube from the beginning to the end :)

    Would it be possible for you to write a follow-up post in which you provide some actual css examples? For instance to take an existing site and describe the whole optimization process and include the before and after css and html? Like some of the previous commenters I am for example still not quite sure how to for example cut down on the number of headings I declare in my stylesheet.

    Another question I have is relating to specifying multiple classes on elements, I found that this does not work in ie6. How do you deal with this?

  27. Hello Nicole, The presentation is really very helpful. But I have a few queries, the most important question I have is that I read somewhere using IDs in your css renders quicker than classes. But you have told not to use IDs, :$ confusion!

    secondly, I am used to retaining original styles and overriding them where needed, by winning the specificity war for the previously used selector. Is this really a bad practice?

    1. @Umair – you can write all your rules to be the same strength, then the one that you want to win just gets put later in the stylesheet. Sort with the cascade rather than specificity and your stylesheets will be much simpler to maintain.

  28. Is using IDs useless when you are just using it for CSS. As for now I use IDs for elements which I know will be unique on the page, as #footer, or #footer-links. Should this be avoided?

    1. I don’t use IDs anymore for styling. If I have a header or footer that is really different, I’ll sometimes scope the components in that area with a class name, that way they don’t pollute the more general page components.

  29. I don’t really get this clearfix – overflow:hidden; overflow:visible; zoom:1;

    I know zoom:1 and overflow:hidden can trigger hasLayout, but why reset it to visible then?

    Does it immediately create a new block formatting context at overflow:hidden and then, when you reset the overflow to visible, still keep that context?

    Seems rather funky to set a property twice in the same declaration

    1. @Kristiaan – zoom triggers hasLayout for IE. Overflow hidden triggers “hasLayout” for better browsers, but will cause issues for IE. So, using the _ hack we set it back to visible for IE only.

  30. @Nicole – ok cheers for the reply.
    In the video it doesn’t show underscores, but I assume they’re supposed to be there?

    Maybe they don’t show due to resolution issues; I noticed there are spaces where you’d except an underscore…

    It looks like this in the video:
    .media{overflow:hidden; overflow:visible; zoom:1;margin:10px}

  31. Style with IDs may be necessary some times, for example, if you a have a certain content which is dynamic (e.g. generated by a script), and you want to give it a certain, specific style. If you already have an element with an Id (pherhaps to identify it in the DOM map), why to create a new css class just for that element?

    In general, I think there are no general rules, there might be approaches (like the OOCSS, which I think is great), but regards to more specific procedures nothing works better like a performance evaluation. If you learn to make a good performance evaluation for each case, the numbers will tell you what is the best to do. And the PE you make it by trial and error, stats, and case uses. You try different options and chose what works best. No general procedural ideology, particularly when website developing is changing so much and so quickly.

    Anyway, great blog, keep posting (straight to bookmarks). Cheers,

    Vicente

  32. Sorry for the late comment, but I’m really wondering why is it a good idea to bloat your html with these numerous classes? And then when one day you want to change the margin of half of your h1 tags from 10 to 15px you have to go through all of the html files and fix this. Isn’t it a bad idea just as naming your classes red/blue (or any other purely decorational stuff) and than one day you change the design from red to pink and you are left with a lot of really meaningless class names?

  33. a typicall example is
    div class=”media h2 ptn pbs mts mbl” -> this is to get a heading looking media box with the respective margins (5px 0 20px 0) and paddings (0px 0px 5px 0px)

    and then one day the designers decide that this element should be more prominent and have more space around it. and this elements is used in dosen of occasions (page, widget, include templates). I would have to find every ocassion and change the class names in a dosen of instances.

    That was my question and I was curious what is you recommendation in this case.

    Another exaple is “leftCol” and “rightCol” which in hypothetical situation one day might change visually so that the content (and its HTML) that were presented on the right / left are now in the center. You can easilly change the css but the html will become meaningless.

Comments are closed.