When it comes to CSS, I believe that the sacred principle of “separation of concerns” (SoC) has lead us to accept bloat, obsolescence, redundancy, poor caching and more. Now, I’m convinced that the only way to improve how we author style sheets is by moving away from this principle.
Doing something like this does narrow the scope but it is not a solution either as it completely ties the styling to the HTML structure.
As a side note, even though the specificity here is not that high, this kind of rules are hard to maintain. In general, high specificity is not the real problem, the real problem is when specificity is all over the place, like here (0,1,0; 0,2,1; 0,2,2; 0,2,3;).
And we finally abandoned descendant selectors. But note that all this was done to facilitate maintenance - not to limit or reduce bloat. Also, note that back in 2009 this approach was called "classitis" or even “The new CSS disease”. This is just to say that what is considered OK today was a big no-no a few years back.
There is also the case of the media object. Is everybody familiar with this? It is Nicole Sullivan who coined that term. The media object is a set of 3 classes meant to be applied onto 3 distinct elements to create a specific layout.
In a sense, the media object is similar to clearfix. The classes involved are related to a specific layout, not to the content. (As a side note - I’m curious - how do you guys use clearfix? Like the rule on the right or like the one on the left?)
Anyway, we wanted to maximize reuse, we wanted to move away from “my widget”, “his widget”, or “her widget” so we thought of adopting something similar to the clearfix philosophy. Which is a class with a single purpose. A class that has nothing to do with content or context.
Inline styling is not that bad. The scope is limited to the element on which we apply the classes and it is “portable” because the styling “follows” the markup. The bad things about inline styling is the specificity, the verbosity, the fact that those bytes are not cached, and also the fact that browsers have to assess those styles once they get to them.
So this is the atomic way. We’ve stopped feeding the styles sheet; instead, we write more classes in the markup. Yes, we do have a “semantic” class on the wrapper but we do not really rely on this for styling.
On the CSS side, it looks like this. Rules are mostly 1 liners. For each class you use you get 1 style and 1 style only (kinda single responsibility principle). We do not use descendant selectors and we do not use classes tied to content either (like using a prefix to reference a container for example). And the same declaration does not exist in multiple places in the style sheet. Our CSS is much much DRYer than what it used to be.
classes are for developers, they don’t make a document more “semantic” (microformats is a different story though). The main goal here is to reduce bloat, so to better achieve this we must ignore content and context as much as possible.
Look at this snippet for example. It creates a working carousel. We put things together in the markup, there is no need for “carousel” rules in the style sheet. If we wanted to show only 2 items per view, we would simply replace W-20% with W-50% - that’s it.
Anywhere does not mean everywhere though. The key is to know when to use a atomic class and when to use a component class. If the style is common to many modules, it is better to use a component class (a “semantic” class).
Also, note that all atomic rules use an ID so we can easily overwrite a style from a component rule like the one above. A atomic class can overwrite any rule based on class selectors - regardless of how many are being used.
We also heavily rely on helper classes. We have many of these. And notice here that even if we could style the “stretched” box using atomic classes alone, we still offer a component rule for this. That’s because many developers are not sure about how all patterns work (the padding trick in this case) so less granularity helps here.
All this to say that even if we do use classic component rules, they are not the norm. They only represent a quarter of our core style sheet. That file is 18KB minified and gzipped. It includes a base style sheet, a grid style sheet, helpers, and atomic classes.
atomic css can change all that. We can share a core file because the styles it contains are not related to content at all. That core file + a custom style sheet weigh less than 30KB. And we can build anything we want with 30KB.
The key points: Maximum re-use of rules because they are content agnostic. Single responsibility rules are easier to manage (add/update/delete). Deleting a module is enough to delete all the styles associated with it.
We try to prevent maintenance issues by looking at what is common across a page. And then we choose to either use atomic classes or component classes. On this slide, the green boxes show styles rather unique to these boxes, while outside of that we see styles common to different modules (i.e.: headings, border, padding). Remember that the goal is not to make our life easier but to provide a better user experience to our users. That’s the agenda. Note that the grid (the page layout) exists in one place, so atomic classes can be used there too.
But if we put Gzip into the picture, then things look even better. That’s because a lot of repetitions means a better compression ratio. From a few tests we ran, it’s about 35% for semantic classes versus 48% for Atomic classes.
Actually, we don’t really do “Responsive” at Yahoo! as we are treating Mobile differently from Desktop. But you could use a suffix to differentiate the classes according to the context in which they apply.