Why you should stop using CSS shorthand

Posted

Forbid something you cannot validate is a dead frost, especially when it's a built-in language feature. But year after year, reviewing code and dealing with regressions and repeatable side-effects, I see how shorthands reducing code quality, making it less readable and error-prone. So let's talk about this.

Box Shadow longhand

CSS shorthand syntax lets you set the values of multiple other CSS properties simultaneously.

You can write

background: #000 url(image.png) no-repeat left top;

instead of

background-image: url(images/bg.gif);
background-position-x: left;
background-position-y: top;
background-repeat-x: no-repeat;
background-repeat-y: no-repeat;
background-color: #000;

and happily switch to another line of code waiting for you, but... here comes the issues.

Shorthand issues

Hard to remember

For around a decade as a frontend engineer, I'm writing and reviewing styles on a daily basis, and still, I can't remember all the shorthands. I was often struggling to understand what my teammate or past me wrote and use MDN as a cheat sheet repeatedly.

The same applies to many others, especially to juniors who are overwhelmed with the amount of information memorized.

It's better to invest in the learning of properties and their values than their specific order.

Error-prone

Shorthands are very error-prone, lemme give you mistake that happens all the time. Developer A wrote component styles:

.component {
  margint-top: 1em;
}

Then developer B extended this component with centered styles:

.component {
  margin-top: 1em;
  margin: 0 auto;
}

Can you spot the issue? Right, the top margin was overwritten, and unwanted sticking to the previous sibling node was introduced.

Surely you can catch it by your eye, and even lint it with no-shorthand-property-overrides as we did for @zattoo/stylelint-config. But in real-world you unlikely will see these overrides together, and lint won't help you:

.component {
  margin-top: 1em;
}

.component__centred {
  margin: 0 auto;
}

The same happens with background, border, transform, and many other shorthands.

Conflicts

Single-lined shorthand has much more chance to conflict when multiple developers modifying its properties.

.component {
<<<<<<< HEAD
  padding: 1em 0.5em 3em;
=======
  padding: 2em 0.5em 1em;
>>>>>>> my-branch
}

Without shorthands

There can be no good without evil

Size

Does size really matter? Yes, but you don't have to manually care for it. Leave it to minification tools like MiniCSSExtractPlugin, and gzip.

Speed

Shorthand is much faster to write. But as was said, not to read.

If you want to be more productive, look at Emmet, most IDEs support it out from the box or have a plugin that can help you speed up typing a lot.

Conclusion

Sometimes we are using shorthand without even knowing about it. It's beneficial to check how shorthand unwraps in a debugger get a clue.

Some CSS properties even don't have longhand props like transform functions (until recent times).

We can't get rid of them fully or even forbid its usage, but I encourage you to use them as little as possible.

References