Resources on writing maintainable CSS
This is a quick post about good resources I came across during my research on how to write more maintainable CSS. It's mostly a document for myself. Hence, I skipped describing stuff that's not new to me. Yet, there might be some helpful hints and pointers for other people as well. I've also included non-exhaustive lists of CSS frameworks, UI-Toolkits, and CSS tools.
The following list is ordered from most to least important, at least from my point of view.
Resources
Harry Roberts - Managing CSS Projects with ITCSS
A talk by Harry Roberts (@csswizardry) in which he describes ITCSS. According to Harry, ITCSS is just a school of thought. So it's neither a framework nor a UI toolkit.
The primary goal is to manage specificity and the IT in its name stands for inverted triangle. I won't go into too many details why there is an inverted triangle, but mainly it is a chart that plots three characteristics (reach, specificity, explicitness) of how you should write your CSS.
Since source order is crucial in CSS, you write global rules at the beginning. Those are the ones that, when changed, have the biggest, perhaps global impact on your codebase. How far-reaching a change of a rule is, is what the reach metric in the inverted triangle describes. Think of element styles for <h1>, <a> and this sort of stuff. Also, think of CSS resets and base color variables if you're using SASS or LESS. However, the more you go down (the output!) of your CSS, the more specific it gets. At the very bottom are utility classes. More on those later. In the middle, you have your components.
Harry describes it very well in his talk, but what you're achieving is to avoid having to "undo" CSS. He's using the concept of a specificity graph to represent a project from a specificity standpoint visually. Try CSS Stats to see it in action.
What else is in the talk?
- Harry shows how he organizes ITCSS in the file system.
- He touches on the typical problems developers have when writing CSS, e.g., how changing one rule damages other parts of the site. You know, the moments when you wish you’d have visual diff testing in place.
- He talks about the general problems of CSS as a language. Among other things, these are the lack of name-spacing and the cascade building up a huge dependency graph.
mdo-ular css at jQuery conference
A talk by Bootstrap co-creator Mark Otto. He presents a pragmatic set of ten rules on how one can achieve more modular CSS. There's even a website describing those rules: mdoular.com. Many details are super interesting, for example, the order in which he writes the properties in a ruleset. To this date, I sort my properties alphabetically, but always felt it weird when doing absolute positioning (e.g., bottom, left, right, top instead of top, right, bottom, left). By the way, also SMACSS is suggesting a particular property order.
Also interesting: limit the use of shorthand declarations for a very practical reason. Why? Shorthands often override more properties than you want. That can cause additional overriding hassle down the line. The community seems to call this the specificity wars.
cssguidelin.es
Also by Harry Roberts. It covers a lot of ground, isn't so much a high-level thing like ITCSS, but instead a guideline for writing CSS. To give a few examples, it's about
- naming conventions,
- avoiding selector chaining,
- specificity of course, and
- how you should use specific
js-
prefixed CSS classes as hooks for the JS parts of your site.
Especially the last one is an interesting thought. Though in times of Vue, React, and Angular it might have become less relevant.
codeguide.co
Like cssguidelin.es, but published by Mark Otto (@mdo). Among other things, he is the co-creator of Bootstrap and a design lead at GitHub. It is shorter than guidelin.es, but there's also a lot of good stuff in there. Overall, I would say it feels more pragmatic.
Its golden rule stands out: "Every line of code should appear to be written by a single person, no matter the number of contributors."
8 simple rules for a robust, scalable CSS architecture
The third collection of guidelines. I particularly like the sections where it talks about how to deal with the lack of namespaces in CSS, how to avoid leaking styles outside a component (siblings) and how to avoid leaking styles inside a component (children).
About HTML semantics and front-end architecture
By Nicolas Gallagher (@necolas). From 2011, often referenced elsewhere and praised on this Twitter collection, it seems to be one of the key articles that led to today’s modern CSS approaches.
Some of the aspects discussed in the article follow:
- Tying class names too tightly to content makes them less reusable.
- It's a lot about reuse, for example how tying a ruleset to an element qualifier is less reusable. I'm guilty of that too, and I wonder why. Maybe it's faster initially because you don't have to introduce new class names? But then again, sometimes YAGNI.
- Also touches on single-class and multi-class component modifiers. The thing in Bootstrap when you wonder why you have to apply both the
btn
and thebtn-primary
class. - Also about class naming patterns, e.g.
u-left
to signal a utility class.
The conclusion is that it's impractical to stick too much to the "semantic HTML" ideology. It's okay to have class names for style and behavior, and it's okay to be pragmatic about using additional tags if that makes a job less cumbersome.
SMACSS
By ex-Yahoo employee Jonathan Snook (@snookca). SMACSS "is more style guide than rigid framework". Other than ITCSS, which is centered around specificity (explicitness) and reach, it's a different school of thought. I'd say SMACSS categorizes by the types of work you do with CSS: base, layout, modules, state, theming. Much advice pops up again in resources, articles, and approaches that came later. For example, to use exclusively use classes to style the modules layer. Has particular handy advice for expressing UI state with CSS.
Since it's a whole book, it has some useful extra chapters, e.g., on selector performance, and how you can shoot yourself into the foot with preprocessors (e.g., through deep nesting).
CSS Utility Classes and "Separation of Concerns"
By Tailwind CSS creator Adam Wathan. This article was the starting point of my research. It nicely draws the arch from semantic CSS to utility-first CSS. Thereby it shows many pain points in the various approaches. E.g., the biggest critique about semantic CSS is the problem to find proper names for components.
Utility-first is not to be confused with Atomic CSS, which can be seen as a utility-only approach. The thing that scares me away from using it to refactor the CSS of my site: I'd need to introduce new tooling (PostCSS).
The Role of Utility Classes in Scalable CSS
A fairly objective article about the role of utility classes. In the end, the author concludes that for large projects, the component approach is more favorable.
In Defense of Utility-First CSS
As the title suggests a pro-utility-first article. Might be useful if you're looking at how an objection of yours could be addressed in this approach.
Can CSS Be Too Modular?
By Harry Roberts. It’s about a question he got if Atomic CSS is too modular. According to Harry, Atomic CSS is one extreme of a pendulum. It's about finding the sweet spot between using utilities only and component-based approaches. Utility-only approach might sacrifice readability and thus maintainability. I can resonate with that claim.
Challenging CSS Best Practices
It's the article that has introduced the Atomic CSS idea to a broader audience.
In the beginning, it does a decent job of putting the approach into perspective with other techniques like CSS Zen Garden. The nucleus of CSS Zen Garden, by the way, is a strict separation of concerns: HTML is for structure, CSS for style and JavaScript for behavior.
It picks up on quite some typical hassles I face when changing the CSS of my projects. For example, I often fear to break things if I delete a ruleset that seems obsolete.
What Is A CSS Framework Anyway?
Again by Harry Roberts, it makes an important distinction between a CSS framework and a UI Toolkit. A UI Toolkit, like Bootstrap or Foundation, entails design decisions which tend to be hard to negate if you want something more custom. UI Toolkits are great when you need a ready-made design (i.e., no one has made a design of your app or site). If you do have a custom design, it's better to write custom CSS from the ground up, potentially supported by a real CSS framework which shall be design-agnostic. InuitCSS is one, and SUIT CSS is another.
Cascade and inheritance
An MDN article describing the cascade, which is a root cause for many challenges in writing maintainable CSS. Harry Roberts describes a CSS project as one big dependency graph (caused by inheritance mostly), and many approaches are about taming the complexity that comes with that.
A Scalable CSS Reading List
A collection of resources on this very topic. It’s full of useful pointers when you’re beginning to research this area.
wtfhtmlcss.com
About the weird bits of CSS and HTML, e.g., margin collapsing. Not so much about maintainable or scalable CSS, nonetheless a useful resource. It is also published by @mdo.
CSS frameworks
- Tailwind CSS, utility-first approach. The idea is to first build a UI with utility classes and refactor recurring patterns (like a button) into components.
- InuitCSS, by Harry Roberts. According to him follows the ITCSS methodology.
- SUIT CSS, by Nicolas Gallagher (@necolas)
- TACHYONS
- Basscss
CSS UI-Toolkits
- Bootstrap
- Foundation
- Primer, described as "our own Bootstrap at GitHub" by Mark Otto in one of his talks
Interestingly enough, Mark Otto is/was involved in all three toolkits. In 2007 he joined ZURB, the company behind Foundation. Since I've not researched UI-Toolkits in particular, the list above is sure as incomplete as it can be. Nevertheless, the distinction between UI-Toolkits and CSS frameworks is crucial. One could think of UI-Toolkits as coded style guides.
Tools
- CSS Stats, an online tool showing different CSS metrics of a website
- Purgecss, a tool to purge unused CSS. Comes in various flavors: as a CLI, a JS API, a plugin for various build systems. It seems there's no online tool though. However, the CLI version appears to be sufficient for one-time use, e.g., when you want to avoid the complexity of a JS build tool.
- CSS Lint, haven't used it. Since there's such a broad way of CSS writing styles, I suspect it's difficult for such a tool to serve all well.