On Challenging Principles and Best Practices
Today my friend Dan Wahlin tweeted:
Very interesting article: Challenging CSS Best Practices (http://ow.ly/q5jyO) Agree or disagree with the suggested approach? #css
The article in question published on Smashing goes into some length to show off a new technique that my.yahoo.com team has tried out. They call it “atomic” CSS. I give kudos to Thierry Koblentz for being willing to stick his neck out by sharing their work and poking the proverbial hornets’ nest.
Principles vs. Best Practices
Oddly enough, at a high level, I find I can agree with Thierry. Too often “best practices” are applied with little to no thought as to whether or not they are actually the best solution. I’ve seen this more times than I can count in my career, and no doubt, I’ve been guilty of it at times. Much like design patterns, so-called best practices need to be evaluated against specific needs and the context of any given problem/project.
The counterpoint, of course, is that really, the point of best practices is to help reduce guesswork for less-experienced professionals. They are not so much for the master as for the apprentice. And given that the apprentice, as a rule, doesn’t have the background to formulate such practices nor to effectively evaluate them, they are good rules of thumb/guidelines for them to follow.
Principles, on the other hand, are a level above practices. They’re not quite eternal and universal, but they are generally at an abstraction level above best practices. As such, they tend to apply to more contexts and can, thus, more safely be assumed in any given context.
Now, Thierry doesn’t seem to make a distinction on this point, and I think it works against him. The principle of separation of concerns (SoC) is extremely well established. It is well-tested and has proven its value so many times that it is generally safe to assume that it has the value that it represents.
CSS and SoC
For CSS, SoC is probably its most fundamental principle, its reason to be–to separate styling from markup. So to make the claim that we should move away from that principle in CSS is to, effectively, advocate moving away from CSS altogether, and we see that in his suggested solution, which is a tiny, marginal step above inline styles.
(As an aside: For contrast, a best practice in this context would be, for instance, keeping CSS in separate files, structuring them a certain way, naming them a certain way, and so on. And to some extent, this is really what he is advocating–a certain way of doing CSS, which implies, inescapably, a use of separation of concerns. It’s just a matter of how much you embrace that separation that is in question, unless you full on advocate for inline styles. And he is admittedly very close to that..)
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.
The thing is that SoC inherently implies some amount of bloat and redundancy (and ergo poor caching, where that applies). This is a trade off, the cost we pay for the proposed greater good of SoC. It doesn’t matter where SoC is applied, when it is applied, you must introduce abstraction layers that must, by their nature, introduce some extra complexity, usually in the form of some kind of interface, which also implies “bloat” and redundancy, because to achieve essentially the same effect with SoC, you have to have at least two things where you would otherwise have one.
In the case of CSS, you have a class declaration on an HTML element and a class declaration in an stylesheet. The interface is, in this case, the class selector. (Of course, there are other selectors that reduce the redundancy by leveraging the innate structure of the DOM, so in that case, you only have the “bloat” in the stylesheet.) If you use CSS at all, i.e., anything but inline styles, you incur the cost of this SoC, so it is just a matter of how much.
What Thierry is proposing is not in actuality that SoC is categorically the problem here but in how that SoC is often practiced with regards to HTML and CSS. He is challenging on the spectrum of SoC available, and that is in a sense not much different from the old semantic vs. non-semantic debate lines. He is just falling very hard on the non-semantic line.
The Great Bloat Migration
As I see it, Thierry’s approach doesn’t really much address bloat nor redundancy. He moves bloat from CSS into HTML. The numbers comparing CSS across Yahoo are irrelevant because they don’t paint the whole picture of the interplay between CSS and HTML bloat. He ends up applying probably numerous classes to elements to achieve the same effect that could be applied with one or even zero classes. And there is a lot of redundancy in specifying the same CSS classes over and over again.
At the end of the day, this is more a matter of shuffling or migrating bloat and redundancy from one place to another, and in the process, you lose cleaner SoC.
Readability, or Back to Morse Code
The classes he chooses become a special language in themselves. Instead of being semantic and contextually meaningful (and ergo readable and understandable by any Joe that comes onto the project), he introduces a new language, on top of the several that people already have to know. He introduces a burden of mental mapping/translation not only of the individual class names but of their total effect on an element.
He claims that this approach helps by not having to look at the stylesheet to see what is applied to it, but all this really does is shift the burden. You must remember (doubtful) or reference (likely) the new class language in order to both understand and modify any given element’s look and feel. Sure, you can become an expert in yet another language, but the benefit really needs to be there.
All Your HTML Are Belong to Us
He admits as much, but if you are using any kind of component or framework that emits its own HTML (under the assumption that you have the styling points you need to change its look and feel), you can’t use this approach. Any reusable components will not support this approach. You must have total control over your HTML.
Back to Best Practices
In terms of best practices, i.e., generalizing, I think Thierry’s approach to the article is a bit off. He implies in a comment that he is not suggesting a new best practice. At the same time, he says he is setting out to show that we should “move away from” current best practices (if not also principles). You can’t create a vacuum like that, Thierry. :) It seems implicit in the article that the suggestion is move away from the old and towards your proposal.
The problem is that I can’t see the proposal as any kind of best practice, nor does Thierry it would seem.
My suggestion for best practices today would be:
As a rule, keep erring on the side of semantic classes (i.e., not “media” but “introduction video” or something more meaningful/contextually aware).
Use the full array of selectors available, but find a balance between reducing class bloat and marrying too closely to the HTML structure through DOM selectors.
Use a tool/language like Sass or Less to help manage your styles.
If you feel the need to put styling into your HTML, just use inline styles. The benefit over the “atomic CSS” approach is that you don’t have to create, use, or learn another language–you can just use the built-in mechanisms. It’s not the end of the world to use inline styles, especially when added dynamically and/or it is roughly as easy for you/your team to edit the HTML as it is to edit the CSS.
If you find yourself struggling to come up with a semantic class name, that might be a good indicator that an inline style is in order. Might as well put style=“color: orange” rather than class=“orange” if you really need that level of specificity without contextual meaning.
There are exceptions, such as browser-prefixed properties/animations/transitions, where creating a non-semantic class might be more useful than inline styles. Another exception would be something like shortcodes, where you need to enable CMS users to achieve a desired effect without knowing CSS and still giving you/theme makers some control over specifics of styling.
Accept that there’s rarely any getting away from the lines being blurred between content, structure, and styling, especially if you need fine-grained, high-quality styling. Learn to live with this blurriness, get your hands dirty, and keep getting stuff done.
The reality is that the bar set by CSS Zen Garden is a bit much. Most of the time that level of separation is extreme and unusual and as such it should not constitute a generic best practice. Most sites can afford a balance of semantic and non-semantic styling because the actual reuse of the components is very low and the need to change one without impacting the other is uncommon, too.
While SoC as a principle is well-tested, that does not make it absolute in all cases. You should gauge your use of it in any given context against the other concerns and make trade offs. And don’t worry, nobody makes the right trade offs all the time. If you’re really not sure, just go with the best practice and learn from your experience applying it.