Separate CSS components into individual files

When I joined a 4 years old project it struggled with UI consistency and frontend code maintainability. Pretty often when there was a need to make a design change it took longer than it could and similar UI elements looked different from page to page. Not rarely a simple change to one element on a page caused a cascade of changes to others.

When I looked into the code I’ve discovered a bunch of problems: code duplications, overly coupled selectors to page layout, ignored semantics ( #spaceships-table applying styles to a table that actually shows astronauts ). These were enormously overgrown files like main.scss, astronauts.scss, spaceships.scss. The files contained a ton of mixed concerns in each and the smallest part they addressed was a page.

In order to clean this mess, I started applying BEM methodology. I managed to start investing small amount of time weekly, sometimes contributing my personal time in the evening. After a couple of years, /ui-elements/ folder appeared, containing dozens of UI components - Blocks, each located in own file. The UI changes became easier, and UI turned more consistent.

Despite this, I still have to fight the urge of newcomer developers to pile up everything into one huge CSS file. So I decided to start collecting arguments and counter-arguments, to make my life easier explaining the same principles over and over again.

Here is one example.

I don’t like making new files just for one style.

“One style” in this context consists of 5 lines of CSS code, providing an alteration in appearance for a sidebar - sizing, padding and border style.

It’s actually better to create many small files than using a single huge. Here is the motivation:

As developers, we want to use our time efficiently, in order to achieve this, we could write styling in a way that would allow us to apply one class, instead of re-writing dozens of lines of CSS code. BEM is the approach that in its core has a purpose of creation re-usable consistent UI components. When we introduce a component we need to think of how other developers or “Future Me” in a year will discover the existing components for a task.

To achieve that, we put every Block in a separate file of the folder we all know about. In this way when we need something then we check /ui-elements/ folder which acts as the catalogue of all available components. When we look into this folder through the IDE’s project tree we can easily see more than 30 available Blocks per one screen scroll. We can even search by file name to get faster what we need.

Now consider the alternative: one huge file main.css where all the stuff is piled up into. A developer needs to open this file and scroll through hundreds of lines of CSS code. One can find a Block definition there but it might require scrolling a lot which is horribly inefficient. Thus even if there are some blocks that developers could reuse, it is not happening because time needed for search and understanding is longer than to write something own.

There are other arguments, which could be even more important. When we separating CSS components into individual files then:

  • We can import only those components onto a page that we need, meaning better user experience because of the faster loading speed due to less code weight.
  • We can package a subset of components into a library and share them between different projects, or make them open source.
  • When a developer works on one component - their changes are isolated to a smaller scope within one file, therefore fewer risks of breaking something and fewer conflicts.

Basically all the same reasons as with any other code. ( We don’t like to put a ton of Ruby classes into one .rb file ) the same with CSS.