December 11, 2019

How we write CSS at Factorial

Finding numerous tutorials and DIY’s online, one thing is clear: Writing CSS seems easy, but writing good CSS is extremely hard. Learn how we do it and what tools we use in order to achieve it.

Good is a very opinionated term. Good is what works for us. Let’s start defining by which characteristics we consider a piece of CSS code to fulfill our requirements.

It is written for people first

While browsers will be the technology the code is targeted at, people will actually read and interact with it. It is not prematurely optimized or overly clever. Making it understandable to your coworkers or contributors is of uttermost importance.

It is consistent

It is written in compliance to a predefined set of rules that all members of our organization follow. These are your braces, colons, white-space, etc. The code base should look like as written by a single person.

It has minimal side effects

Bad CSS has the problem of leaking into other areas. This often leads to unnecessary overwrite and a bloat of the code base. Could the code be placed anywhere regardless of context? Would it break anything? Would it create any conflicts?

It is composable

Can it be split up further? Can it be used to build bigger, more complex components from it? Is it configurable from the outside? Do users need to know about its implementation details?

It is reusable

Does it entirely solve a particular problem? How many dependencies does it have? Could it be abstracted in a reasonable manner? Could it be published as module?

What we use

We tried a lot of different options: I personally argued about semantics, wrote CSS using web standards school, wrote LESS, wrote SASS, wrote SCSS, used grid frameworks, used Compass, used Foundation, used Inuit.css, used Bootstrap. You name it, I probably used it. Every step I took brought me closer to our current setup.


We follow the design principles and naming convention of SUIT CSS. For the most part we understand it more as a methodology than a framework. Basically it is principles of computer science applied to CSS.

We like that …

Here’s how it is written:

.u-utilityName {} 
.ComponentName {} 
.ComponentName--modifierName {} 
.ComponentName-descendentName {} {}

The SUIT CSS naming convention

It’s what stuck with us. It allows us to write our own components backed by the confidence of having a clear rule set. We found it to be extremely helpful in our day to day business.


We use PostCSS to bundle and process our CSS files. SASS is a wonderful and industry-accepted tool, but we think it is too powerful. CSS is not a programming language. Augmenting it with a non-standard superset can easily lead to bad production CSS by developers acting overly smart.

We want to write as closely to the W3C specs as possible. That means we constrain ourselves with a minimal set of processors. They make our lives easier, but are also likely to be implemented by browser vendors in the future2:

Deviating from this list is perfectly fine. It primarily forces us to actively decide weather we need a particular feature or not. For example: there are cases where we would need something like extends or mixins, but those are the exception. Rules are meant to be broken. But we need a reason in order to do so.

How we enforce it

We have a shared stylelint configuration with a fixed set of rules. It extends the configuration of SUIT CSS with a custom property sort order that is inspired by and focuses more on the browser’s box model. The rulesets are enforced through gulp-stylelint. Additionally I use a SublimeLinter Plugin for immediate feedback in my editor3.

Putting it all together: Working with SublimeText and the activated stylelint plugin. If you look closely, you can see the red dots and status messages of the linter.

Putting it all together: Working with SublimeText and the activated stylelint plugin. If you look closely, you can see the red dots and status messages of the linter.


CSS is an almost untamable beast. By the very nature of the web it is ever changing. What works today, might not work tomorrow. Our approach is an educated guess into the future at best. The problem of style encapsulation might become obsolete. People start putting CSS in JavaScript already. Widespread support for web components might arrive someday.

Being able to adapt and enjoy the accompanied challenges, is what makes our job fascinating.

Further Reading

1 We couldn’t care less how you call it. See caniuse, e.g. CSS custom properties. 3Editors are user preference at our office.

Milan Matull

Milan Matull

Managing Partner