DEV Community

loading...
Cover image for Harry Potter and the Order of CSS

Harry Potter and the Order of CSS

Anton Korzunov
Reinventing the wheels.
Updated on ・10 min read

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, and here are the results:

poll results

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

.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;
}
Enter fullscreen mode Exit fullscreen mode

Beautiful? That's how common CSS looks like after a few years without any control.

ABCSS

Sort it alphabetically

.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%;
}
Enter fullscreen mode Exit fullscreen mode

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

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...

.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; 
}
Enter fullscreen mode Exit fullscreen mode

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 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

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

  • 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

  • Smaller teams may prefer to cluster related properties (e.g. positioning and box-model) together idiomatic-css.

  • 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.

  • 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

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.

  • Larger teams may prefer the simplicity and ease-of-maintenance that comes with alphabetical ordering. again idiomatic-css

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 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

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

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.
  • 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
There are groups first, and alphabetical ordering is used only inside one group.

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

See also:

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 - 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

// 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
}
Enter fullscreen mode Exit fullscreen mode

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

  • 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

// package.json
"lint-staged": {
    "*.scss": ["stylelint --fix", "git add"],
}  
Enter fullscreen mode Exit fullscreen mode
  • configure stylelint
// .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
    }]
  }
}
Enter fullscreen mode Exit fullscreen mode

or using stylelint-semantic-groups

  • yarn add stylelint-order stylelint-semantic-groups
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,
  },
};
Enter fullscreen mode Exit fullscreen mode

Discussion (11)

Collapse
petedermott profile image
Pete Dermott

It has to be alpha for me.

There is zero a learning curve for any new developers who come into the team who may not be 100% au fait with CSS, you don't have to worry about 1 rule overwriting another, plus it's the easiest thing in the world to remember.

With groups you'll have to remember what prop goes with what group, the order the groups go in, yea you could get a tool to do it but why complicate what is already probably a pretty complicated build process to spit out some HTML?

At this point not sorting at all would probably drive me a little bit crazy...

Collapse
thekashey profile image
Anton Korzunov Author

Yep, this is a most popular alpha-pro opinion - the absence of a learning curve.
But what does alpha sort solves for you? I mean - everything should do something valuable, and what is valuable for you here - why not random sort?

Collapse
petedermott profile image
Pete Dermott

It just keeps things neater whilst not having a big learning curve and I've gotten tripped up by the duplicated properties a few times in the past.

Yes, it probably would be faster not to bother but I've done it for so long I'm just a bit OCD about it at this point.

Collapse
puiutucutu profile image
puiu

Not really sure I agree with this reasoning.

For starters, anyone coming in that is uncomfortable with CSS is going to be just as lost with alpha order or grouping. At least with the grouping by role/function, the CSS-shy dev will be forced to understand why certain rules in CSS absolutely must go together.

Collapse
petedermott profile image
Pete Dermott

Why would they be lost with alpha order? Most people know the alphabet right?

Collapse
kenbellows profile image
Ken Bellows

Definitely some variant of group sort. I've personally dealt with both, and my experience is that when I'm modifying CSS, I'm very often modifying a few related properties (top & left, width & height, margin & padding, font-family & color, etc etc etc). The constant jumping up and down through a stack of properties that ABCSS causes is an absolute nightmare. Grouped CSS saves so much time in the long run. If tools exist to do it for you on save, then it's zero extra work, and the consistent ordering of groups gets absorbed subconsciously after like two hours.

Collapse
thekashey profile image
Anton Korzunov Author
  • An advantage of groups - easy to find all the props about position or display. Usually, you need all them together to "understand" how style works
  • An advantage of an alpha sort - easy to find a single property, and you often looking for a single prop, but almost impossible to find all you are looking for, and it's also happens quite often.
Collapse
ggenya132 profile image
Eugene Vedensky

I think groups are conceptually better but like you said, the draw back is that different groups mean different things to different people. If we could get a few consistent schools of thought on which properties to group together (for less obvious ones...), we could probably really get some best practices going. For now, alpha is probably the fastest way to establish some consistency with minimal draw back.

Collapse
nhoizey profile image
Nicolas Hoizey

stylelint-semantic-groups is great, thanks for that! 🙏

Collapse
myfonj profile image
Michal Čaplygin

Another strong ABCSS advocate is Jens Meiert: meiert.com/en/blog/on-declaration-... . He is AFaIK author of the original Google HTML & CSS guide.

Collapse
thekashey profile image
Anton Korzunov Author

Yet again, and quite unfortunately, I haven't found any "strong" opinions.

But I appended this article with a conclusion, where I did say - sorting is a poor man solution - it does not solves the main problem. ANY sorting does not the solving the problem.

What does:

  • locality - keeping similar things together
  • separation of concerns - splitting one big problem(hard to load into your brain) into smaller ones. This is alpha and omega for almost any CS problem.

Just think about CSS from a "JS" prospective. What do we do to keep our code manageable - we do fight Cyclomatic complexity, and KISS.

  • Alpha sorting is making it even worse. Are you sorting your functions? CSS selectors? Alpha sorting is breaking coherence and locality,
  • Group sorting is not a solution for the problem - it's still a WALL OF TEXT.
  • Grouping (just add a blank line between groups) - magically - do the job.