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.
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.
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.
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.
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."
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).
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
- Also about class naming patterns, e.g.
u-leftto 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.
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).
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).
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.
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.
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.
It's the article that has introduced the Atomic CSS idea to a broader audience.
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.
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.
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 collection of resources on this very topic. It’s full of useful pointers when you’re beginning to research this area.
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.
- 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)
- 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.
- 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.