How to Sort CSS Declarations
The order of writing CSS declarations is arbitrary, with two important rules.
- Unrecognized or invalid declarations are silently ignored (e.g. this is how vendor-specific and unsupported properties aren’t causing problems).
- If a property is declared more than once, the last declaration applies (e.g. this is how vendor-specific declarations are correctly overridden by the standardized property once the user agent has started supporting them).
Yet, when you inspect a CSS document, you might feel like you’re reading a list written in random order. This can be rather sloppy, not to mention the frustration during development when trying to modify a property without success and after wasting some considerable time looking for a suspected roguish, inherited value coming from the cascading nature of CSS or maybe from some Javascript, finding that it was actually defined in the very same declaration block, a few lines later on.
I often see various “house rules” trying to bring some order to this chaos. For example some people like to group declarations first by layout, then by color, then by typography, then perhaps by animation, and so on, but since there’s no consensus on the preferred order of these groups, let alone the lack of agreement on just how many such groups exist and exactly which property belongs to what group, this isn’t an objective solution. It also doesn’t help when someone by accident just adds a declaration as a quick-fix at the end of the declaration block, and it stays there, forgotten – working as expected, for the moment, but remaining a hidden source of problem for the future.
In theory a CSS linter could help spotting these issues, but what if you really need to provide declaration for the same property multiple times? (This is exactly how one would define alternate values and let the user agents pick whichever value they can interpret.) Either you need to add local overrides for the linter or get a lot of false warnings. It’s a universal law that false warnings are a sure way of asking for trouble as you’ll have a hard time catching the real error messages. Maybe this technique isn’t required today in the age of evergreen browsers, but frontend technologies change so often that I wouldn’t be surprised for a moment if history repeated itself in this aspect again, and frankly, the more complex your build process is the harder it is to use and keep it functional for your team.
I simply like to have my declarations ordered alphabetically by the property names, with the only exception of vendor-prefixed properties still going before the standardized properties. This way I can quickly find any property I might be looking for and it’s trivial to check for duplications as well. Actually, wherever the exact order is not important, even in programming languages – when defining a map/associative array/dictionary, especially when writing Vue.js components for example – I also declare everything in alphabetical order and so far I haven’t regretted this decision once.