Structuring CSS has long been a struggle, due the limitations of the language. There seem to be a growing consensus that some of the best practices, particularly the admonition against “classitis” and introducing non-semantic elements, are actually detrimental. Here’s a round-up of some discussions on the issue.

Before looking at semantics, a couple of reminders from back in the day about performance.

Performance Impact of CSS Selectors

Steve Souders
Performance Impact of CSS Selectors
Simplifying CSS Selectors

Two conclusions:

  • Based on these tests I have the following hypothesis: For most web sites, the possible performance gains from optimizing CSS selectors will be small, and are not worth the costs. There are some types of CSS rules and interactions with JavaScript that can make a page noticeably slower. This is where the focus should be
  • The key to optimizing CSS selectors is to focus on the rightmost selector, also called the key selector

Writing efficient CSS

David Hyatt
Writing efficient CSS

Main points (bear in mind, this is rather old):

  • Matching rules are split into families - either tags, IDs, classes, universal. It’s more efficient if each selectors is in just one of these categories.

  • Don’t qualify ids or classes with tag names - a#home or a.sidebar
    better: #home or .sidebar

  • Use the child selector instead of the descendant, but not for tags
    .sidebar > .home but not div > a

  • some rules are inherited by elements (e.g., list-style-image, font-size), make use of that

And now, for some modern stuff.

CSS Selector Performance has changed! (For the better)

Nicole Sullivan
CSS Selector Performance has changed! (For the better)
Main points:
  • Forget what David Hyatt said. That was a long time ago. CSS engine have now been optimized to the point where it makes no difference.

Profiling CSS for fun and profit. Optimization notes

Juriy Zaytsev
Profiling CSS for fun and profit. Optimization notes.

Main points:

  • There are now tools to profile CSS in Opera and Webkit.

  • Some selectors are slower than others - universal selectors, multiple classes and others

  • The whole post is a summary of main points, no point in me summarizing it.

CSS for Grown Ups: Maturing Best Practices

This is my favourite of the lot.

Andy Hume
CSS for Grown Ups: Maturing Best Practices (audio)
CSS for grown ups: maturing best practises (slides)

His main points:

  • nothing wrong with “classitis” if it allows us to decouple the CSS from the HTML markup.

  • the fewer tags in the CSS - the better. E.g., .social .link is better than .social a, because it is not reliant on specific type selectors

  • Sass / LESS / Stylus are all good tools, but are an extra step and can’t be removed easily from the stack if the problem they were trying to solve has gone away

  • OOCSS / SMACSS / CSS Lint are better, because they are approaches

  • he advocates a multi-layered approach similar to SMACSS with layout, module, base, and document layers (missing the states and theme layers). The document layer is the HTML code.

  • He advocates thinking more in term of modules and using CSS cascade rules to avoid too complex selectors. He uses a double slash convention to signify a selector should appear after another, e.g.

    .promo-box { .... }
    .promo-box--eco { /* need to be after promo-box */... }
  • advocates prefixing all selectors introduced by JavaScript with .js-

  • A selector like .promo-box h3 is bad because it mixes the module layer (.promo-box) with the document layer (h3). He’d replace it with promo-box .promo-box-h

  • h1 { font-size : 2em; } h2 { ... etc is also bad - this mixes base and document. He suggests either using custom classes like .h1 { ... or something more typographic like .masthead { ... }

  • modules variations shouldn’t be associated with IDs of elements - e.g., #sidebar .promo-box is bad, better use .promo-box { ... } .promo-box-light { ... }. The same holds for page specific styles, i.e. when adding a class to the body element to signify a different page

  • He doesn’t like the syntax for media queries for the same reason. Therefore he created selector-queries, a JS tool to allow him to restructure his CSS more semantically

  • He doesn’t mind small presentational classes such as .margin-top { ... }, .gutter-left { ... } etc.

  • It’s a good idea to add extra semantic elements in the document when needed. For example, small icons like comment icons on blogs, instead of of being added to the container <p class="icon icon-comment"> should have their own semantic tag, and the icon style applied to that. Twitter bootstrap has made i a popular choice.

  • He advocates writing online style guides with code samples. Good examples are Twitter Bootstrap, and Paul Robert Lloyd’s styleguide. Plus he shows one he’s been working on, which looks quite good.

Our Best Practices Are Killing Us

Nicole Sullivan
CSS Tools for Massive Websites (video)
Our Best Practices Are Killing Us (slides)

Her main points:

  • A little bit of classitis is not bad

  • Counting specificity rules. For each CSS selector, count the number each of inline, IDs, classes (and pseudo classes), and elements (and pseudo elements), in that order. For example,
    #sidebar ul li a.myclass:hover {} has: 1 ID, 2 classes, 3 elements, whereas
    * {} has: 0 ID, 0 classes, 0 elements, hence it ‘loses’

  • !important adds another stack of ID, classes, elements to the left of everything, so the specificity stack becomes:
    ID !important, classes !important, element !important, inline, ID, classes, important, element.

  • Not keen on preprocessors, but there are some good ideas in there that are becoming part of the CSS Working Group

Top 5 Mistakes of Massive CSS

Nicole Sullivan
Stoyan Stephanov
Top 5 Mistakes of Massive CSS (video)

Their main points:

  • Print style sheets often slow down rendering even though they are not used

  • Used a small PHP script to open files in IE. The script creates a new COM( “InternetExplorer.Application” );

  • A lot of sites neither GZip, nor minify nor combine CSS files.

  • Serving CSS files (and images) with cookies is pointless

  • Advocates Object Oriented CSS. Basically abstract UI elements into patterns. Note that CSS objects != JS or backend objects.

  • Use star and underscores hack, if you have to

  • Avoid IDs, style classes only

  • Avoid !important, although they are ok for mixins - but not too many

  • When optimizing existing CSS, use grep to look out for:

    • floats - too many is a symptom of a bad grid

    • margin / padding - they can often be abstracted

    • font-size - there are only a few readable font-size actually used on a site, and nobody notices 1px differences

Help! My Stylesheets are a Mess!

Chris Eppstein
Help! My Stylesheets are a Mess! (slides)

He says…

  • Classitis is not so bad after all

  • Advocates no less many layers: grid, layout, background, container, spacers, typography, foreground, margin / padding, widgets, theming

  • Advocates naming styles together with designers

About HTML semantics and front-end architecture

Nicolas Gallagher
About HTML semantics and front-end architecture

His main points:

  • Pretty much echoes what Andy Hume said

  • advocates prefixing all selectors introduced by JavaScript with .js-

  • finds the Twitter Bootstrap practice of using universal CSS selectors, e.g. [class*="btn-"] { risky. Instead he prefers multiple classes, e.g. .btn .btn-close {

  • long class names or multiple selectors don’t really matter after CSS files are minimized and GZipped. Removing 30000 class names from a file only removed 1.6k after compression

  • he advocates structured class names, somewhat similar to BEM

Measuring and sizing UIs, 2011-style

Harry Roberts
Measuring and sizing UIs, 2011-style (and beyond)

His main points:

  • Use percentages for main layout sections

  • Use no units on any module / widget

  • Use rems with a pixel fallback for fonts

  • Unitless line-heights

  • pixels only for external icons and the like


A New Front-End Methodology: BEM

I think BEM is taking things way too far, but it may make sense in some scenarios.