Harry Potter and the Order of CSS
Tags: css, stylelint, order, styleguide
Published: 2019-03-25 08:19:29

---
title: Harry Potter and the Order of CSS
published: true
description: The battle between ABCSS(alphabetical sort) and Groups(rule grouping)... BEGINS NOW!
tags: css, stylelint, order, styleguide
cover_image: https://thepracticaldev.s3.amazonaws.com/i/jtpbp4dmoudsk7y4cqsw.jpg
---

So, first of all - this is a not a common battle. It's not about `CSS` versus `CSS-in-JS`, not `atomic CSS` versus `BEM`, not `LESS` vs `SASS`. This battle is about THE ORDER.

This battle is between ORDER and CHAOS. And between ORDER and,... _another_ ORDER. In short - about different ways to sort CSS __properties__. No more, no less.

In short - there are 3 ways to do it:
- don't do it. Write any CSS as you can. This is most popular way
- group properties by sense. Just put some stuff together. This is quite popular way.
- order all the properties alphabetically. The easiest, but less popular way.

> From now lets forget about the first way. It's not the way.

### 2012 
There was a [good poll from css-tricks](https://css-tricks.com/poll-results-how-do-you-order-your-css-properties/), and here are the results:

![poll results](https://thepracticaldev.s3.amazonaws.com/i/erl34nrwpmphg3uvikhd.png)

Back in 2012 "group sorting" was more popular, but it's 2019 already, what was changed?

The difference between alpha(betical), __ABCSS__ as it known, and __group__ is quite sound, but it's better to make this difference more clear and define these terms yet again.

### Initial state
Lets start with an ideal CHAOS from this [prettier issue](https://github.com/prettier/prettier/issues/1963)
```css
.wrapper {
    top: 20px; /* is it absolute? fixed? You begin searching downwards */
    margin-left: 20px; /* Any other margins applied? */
    display: flex; /* How is this flexed?  searching for justify / align / flex rules */
    position: absolute; /* ah absolute */
    height: 100%;        /* and width? */
    margin-bottom: 20px;
    border-radius: 5px;  /* Is there even a border? */
    color: red;
    justify-content: center;
    margin-left: 2px;
    left: 0px;
    width: 100%;        /* and height? */
    border: 1px solid red;
}
```
Beautiful? That's how common CSS looks like after a few years without any control.

### ABCSS
Sort it alphabetically
```css
.wrapper {
    border: 1px solid red;
    border-radius: 5px;
    color: red;
    display: flex;
    height: 100%;
    justify-content: center;
    left: 0px;
    margin-bottom: 20px;
    margin-left: 20px;
    margin-left: 2px;   /* ouch? */
    position: absolute;
    top: 20px;
    width: 100%;
}
```
It just helped notice that we had two `margin-lefts`. It would be easier to add a new property next time, especially if all the sorting is done automatically on `stylelint` level - __you don't have to sort anything by yourself__ (and that's a very __bold__ statement!).

> The main __advantage__ of alphabetical sorting - easier property location. You are just scanning a table, like a glossary, and yep, here is the property I am looking for.

The main __disadvantage__ - `height` goes before `width`, `left` goes before `top` and there is some _distance_ between them. There is even `position:absolte` between `height` and `width`, as well as between `left` and `top`.

Alphabetical sorting is __scattering context__. 
But it's not a problem if you have _short_ styles, like twice shorter than in the example above - the complexity comes with a size.

> Personally I can’t live without sorting because when I work with width I need height as close as possible, not white-space; I need bottom right after position not after border; font is pretty useless close to float, etc. [Vadim Makeev](https://meiert.com/en/blog/on-declaration-sorting/#comment-239223)

It worth to mention - alphabetical sorting is not working well for big styles, but quite handy for a small ones. Atomic, or functional CSS is just perfect fit for them.

> In atomic CSS you are creating myriad small classes, every one only about small "thing". Like position, or colors, or size, or border radius. You know - atomic CSS is about separation of conserns, and about __grouping things together__.


I've used some online tool to make it. A vast amount of online tools, plugins for IDEs and CLI tools support alpha sort out of the box. 👍 - easy to use. While it's easy to use. Not easy later.

### Groups
Sort it in groups, cohorts, buckets, clusters. Into the multiple orders...

```css
.wrapper{
    position: absolute;
    top: 20px;
    left: 0;

    display: flex;
    justify-content: center;

    width: 100%;
    height: 100%;
    margin-bottom: 20px;
    margin-left: 20px;
    margin-left: 2px;

    color: red;

    border: 1px solid red;
    border-radius: 5px; 
}
```
This time it's more about `separation of concerns` - all properties are grouped(clustered) into buckets by a sense. The ordering principle is known as "Outside-in":
- Layout Properties (position, float, clear, display)
- Box Model Properties (width, height, margin, padding)
- Visual Properties (color, background, border, box-shadow)
- Typography Properties (font-size, font-family, text-align, text-transform)
- Misc Properties (cursor, overflow, z-index)

The problem - there is __more than one standard__ around it. To be more concrete - more than five. And that's a problem. Or not?

> And, yet again - sorting itself is automated by a tool, [CSSCOMB](http://csscomb.com) this time.

The main __advantage__ - all properties are grouped by a common sense. All flex properties - together. All position, left, right, top, bottom - together. Colors? - together!
- If you need to add something - add somewhere and let __a tool__ do the job.
- If you need to find something - look for a group, then look inside a group. By the way - this is WAY faster than a linear search in a previous case. (really - O(logn) vs O(n))

> This requires some clarification:
- with alpha sort - you are looking for a beginning of the line, pointing beginning and the end of "your" first letter. Then you are going thought this subblock and that's done. That's basically O(n). After some training - O(n/2), as long you will know "where" look for a prop.
- with group sort - you know "where" to look for a prop - groups have a constant position, and then go through small subset, and that's done. That's basically - O(3), not even "log n".

The main __disadvantage__ - you have to learn how to separate conserns. 99% respondents said that this is a big problem - to write _grouped_ CSS. But it's a tool job, not yours. So it's not the problem at all.

> And, yeah, there is a more than one standard, but it's not a problem with then ordering is done by a tool. The same problem as with prettier.

#### Sorting inside group
Sorting inside group is __almost__ alphabetical. It's always alphabetical except left/right/top/bottom/width/height, which are subjects for _established expectations_, like `x` should go before `y`.

## The Poll

{% twitter 1109934385363509248 %}

So, I did some research around this problem.
- 2012y, css-tricks reported 45% devs uses groups, 14 - alpha sort, 39 dont use anything
- poll created today (and not yet finished) - 50% for groups, 25% for alpha, 25% dont use anything

#### Reasons to use groups:
- Groups is the most natural way of putting things together: that’s the way your write them. Imagine if you’d have to write words in a sentence in the alphabetical order. Top, right, bottom, left naturally belong together, just right after position: absolute 
{% twitter 1109956283929714690 %}

- A good reason for groups could be atomic CSS - atom/utility are usually bound to a one "group", it’s a natural way to for functional frameworks. So “normal” CSS might look like combined atoms - ie grouped
{% twitter 1109943404723466242 %}

- Smaller teams may prefer to cluster related properties (e.g. positioning and box-model) together [idiomatic-css](https://github.com/necolas/idiomatic-css#declaration-order).

- There are pros and cons for both ways. On one hand, alphabetical order is more universal (at least for languages using the latin alphabet), so there is no arguing about sorting one property before another. However, it seems extremely weird to me to see properties such as bottom and top not right next to each other. Why should animations appear before the display type? There are a lot of oddities with alphabetical ordering. On the other hand, ordering properties by type makes perfect sense. Every font-related declarations are gathered, top and bottom are reunited and reading a ruleset kind of feels like reading a short story. [SASS guide](https://sass-guidelin.es/#naming-conventions).

- group sorted files are smaller by 2% after gzip. Magic. There is an  article, which analyses 5 different ways to order css props from compression prospective. [read study](http://peteschuster.com/2014/12/reduce-file-size-css-sorting/)

> Yes, gzip could compression could depend on the sorting, that's ok.

#### Reasons not to use groups
- "Groups" is great if it means the same thing to everyone. It usually doesn't. You could probably automate enforcement of groupings and then you're square.
{% twitter 1109964896874033152 %}

- Larger teams may prefer the simplicity and ease-of-maintenance that comes with alphabetical ordering. [again idiomatic-css](https://github.com/necolas/idiomatic-css#declaration-order)

#### Reasons to use alphabetical:
- I used to do by "group" but it's too subjective. Plus there are plenty of addons to alpha sort a set of lines. Also Chrome Dev tools `computed style` is alpha. (_lost reference_)
- alphabetically. anything else means anyone coming onto the project also needs to learn your pattern.
- my own company is using alpha sort, without explanation (that was a surprise for me).
- It’s easy to lint, there are tools to format it automatically, and there is no learning curve.
- When editing a CSS file, finding the declaration to change can be time consuming. To reduce the __cognitive load__ when both reading and writing rules, write them alphabetically. It's the only sorting rule that is future-proof because it's opinionless. When you will have more than 10 CSS declarations in a rule, you will be glad to know where to find what you were looking for in a split second! (CSS in
44 minutes)
- [google css guide](https://google.github.io/styleguide/htmlcssguide.html#Declaration_Order) recommends ABCSS.
> Based on many years of experience in many different environments I can only, and that strongly, recommend to sort declarations alphabetically. We can just keep things simple. The only other alternative that means little work for us is not sorting. And not sorting is not useful, for structured code is more manageable and more maintainable code. [On Declaration Sorting in CSS](https://meiert.com/en/blog/on-declaration-sorting/)

### Terms used

 - __cognitive load__. It would be fair to say that "cognitive load" to write code would be zero, if a tool would sort it, and would be much lower if grouping would never left you with 10(20) lines of always different CSS code. We already talked about "complexity", and that would be clear - is lower for groups.

- "without explanation". If you don't have explanation why something is better of worse than another - you have only rule of thumb. It's not the bad thing, it could be just your intuition, but not in this case.

Btw, about google

{% twitter 1110075645726478336 %}

So, TLDR
- most of us (and me usually included) are not giving a shit about _ordering_ of CSS props. Most of us also not giving a shit about CSS itself. You know - [The Great Divide](https://css-tricks.com/the-great-divide/).
- CSS-in-JS is also not quite encouraging best practices.
- Best practices like atomic CSS are besties with groups (by design), while BEM, unfortunately, has nothing about property ordering as a part of it's standard (except B(size) and E(style) separation) :(

It's actually a bit unexpected, that such opinionated thing is not well established and defined, and I have to write this article.

> Fun fact - groups and alphabetical order could be besties, for example to lint your module imports, like [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md)
There are groups first, and alphabetical ordering is used only inside one group.

- Style lint for groups: https://github.com/constverum/stylelint-config-rational-order (or csscomb)
- Style lint for alpha sort: https://github.com/hudochenkov/stylelint-order

So far I heard quite reasonable arguments pro `grouping`, but not a single (reasonable for me) pro alpha sort.

See also:
- (about all variants) https://mediatemple.net/blog/tips/different-logical-ways-group-css-properties/
- (about groups) https://webdesign.tutsplus.com/articles/outside-in-ordering-css-properties-by-importance--cms-21685
- (about abcss) https://medium.com/@jerrylowm/alphabetize-your-css-properties-for-crying-out-loud-780eb1852153

PICK YOUR SIDE, and explain your position. I've got some popcorn to share.

> My own view... is about pattern matching. Humans are good at it. ABCSS is easy to learn, but is there any patterns to match? Groups might be hard to learn, but it is all about patterns... you may match.
Don't think about today - think about tomorrow. Yes - __think__, dont blindly use.


# Conclusion

It would be a bit unexpected for you, for __ordering does not matter__. At all. We were talking about ordering as a way to... to what? for what? What we were trying to solve with the ordering?

## WHAT IS THE PROBLEM? AGAIN!

- Are there any problems with small styles? Like 1-3 rules long? Obviously - __no__.
- Are there any problems with big rules? Like 30+ rules long? OH YES!
- Are there any problems in between? Sure.

> Complexity comes with a size. Only size matters.

Why do you have to have big styles? Well, you don't. There is no reason to have big styles. Once you created something big - perform __decomposition__, and __split__ it into the pieces, or helpers, or atoms - __Eat Bear In Parts__.

- Let's imagine you are using `SASS/LESS` - just extract some common things to mixins. Move everything off styles and assemble it back.
- You are using [SMACSS](https://css-tricks.com/methods-organize-css/#article-header-id-1) - well styles are natively separated by concerns.
- BEM? B is for size, E is for everything else - separation of conserns.
- Atomic CSS(like bootstrap, tachyons) - well each atom incorporates "a thing", small and sound thing.
- Molecule CSS(like bulma, invented the term just today) - each style is applying atomic operation on the molecule.


> It's always about two things - separation of concerns, and keeping things as small, as possible.

Grouping is doing the same, while alphabetical sort is keeping you styles as big and as unmanageable, as they were. It does not addressing the "real problem" at all.

Let's try to avoid the "real" problem

```diff
// grouped
.wrapper{
    position: absolute;
    top: 20px;
    left: 0;

    display: flex;
    justify-content: center;

    width: 100%;
    height: 100%;
    margin-bottom: 20px;
    margin-left: 20px;
    margin-left: 2px;

    color: red;

    border: 1px solid red;
    border-radius: 5px; 
}

.wrapper{
    position: absolute;
    top: 20px;
    left: 0;
    
-    display: flex;
-    justify-content: center;
+    FLEX-CENTER

-    width: 100%;
-    height: 100%;
+    ALL-SPACE

-    margin-bottom: 20px;
-    margin-left: 20px;
-    margin-left: 2px;
+   MARGIN-BETWEEN // margin-bottom: 20px;  

    color: red;

-    border: 1px solid red;
-    border-radius: 5px; 
+    BORDER-RED
+    BORDER-ROUND
}

.wrapper{
    position: absolute;
    top: 20px;
    left: 0;
    
    FLEX-CENTER

    ALL-SPACE

    MARGIN-BETWEEN

    color: red;

    BORDER-RED
    BORDER-ROUND
}
```

This is still a custom style, but I've replaced "common" styles by `things`(mixings of any sort). And, btw, a good thing should affect properties from only one group. It is easy this time? 


> When I explained the problems with type sorting in CSS I realized that the type sorter’s motivation was a particular problem, not just mere preference. It was something more fundamental, something that has caused us web developers more headache. The underlying problem is that people repeat themselves too often in CSS—or repeat the wrong code too often, respectively. [CSS, DRY, and Code Optimization](https://meiert.com/en/blog/css-dry-and-optimization/)

- Get one big style
- Separate into "things", and groups are the good things.
- Extract common

# Scripts
Add:
- `lint-staged` - npx mrm lint-staged
- add `stylelint`, `stylelint-config-rational-order`, and `stylelint-order`

- configure linting on commit
```js
// package.json
"lint-staged": {
    "*.scss": ["stylelint --fix", "git add"],
}  
```
- configure stylelint
```js
// .stylelintrc
{
  "plugins": [
    "stylelint-order",
    "stylelint-config-rational-order/plugin" // remove to keep only alpha sort
  ],
  "rules": {
    "order/properties-order": [],
    "plugin/rational-order": [
      true, {
      "border-in-box-model": false,
      "empty-line-between-groups": true
    }]
  }
}
```

or using `stylelint-semantic-groups`
- `yarn add stylelint-order stylelint-semantic-groups`
```js
const { semanticOrdering } = require('stylelint-semantic-groups');

module.exports = {
  plugins: ['stylelint-order'],
  rules: {
    /* optional by recommended */
    'order/order': [
      'custom-properties',
      'dollar-variables',
      'declarations',
      'at-rules', // <-- important, `@media` should go before `&:pseudo`
      'rules',
    ],
    /* the actual usage of this package */
    'order/properties-order': semanticOrdering,
  },
};
```