CSS For Large Projects And Large Teams

You're setting up a new web application for your company. It's going to be a large application that will be maintained and expanded for years to come. There's going to be a large development team. Over time most if not all the original developers will move on to other projects or other jobs. New developers coming into the project will need to start producing without understanding the whole project and without breaking anything. How do you set up the CSS for the project?

When you set up the CSS for a large project, you have a few goals,

  1. I can write CSS (or any other code for that matter!) without fear that I will break other parts of the application.
  2. I can write CSS without fear that the developers working on other parts of the project, or the developers who will be hired next year, will break my code.
  3. When I'm trying to make my piece of the UI work, I can easily find all the existing CSS which affects its appearance. All of that CSS should be organized sensibly, not sprinkled across many files throughout the project.
  4. The system should be simple and readily understood so that it will continue to be applied long after the current development team is gone.

This is a little tricky with CSS because all styles are global. It's very easy for a developer to add a new style that impacts other developers and other screens. If I have a screen that has a red button, and I stick this in a CSS file somewhere,

.redButton { background-color: red }

There's a decent chance I'm going to break someone else's code that also has red buttons. Or the new developer they hire a year from now will break my screen with his red button.

DON'T WRITE GLOBAL CSS STYLES

This is the most important thing all developers need to understand. Yes, there is a need for some global styles that apply to the whole project. Those are usually written at the early stages of the project. They should be put someplace obvious where everyone will see them. Maybe you put them in a folder called "Global CSS." But once the project is underway, no one should touch the global styles or add new ones except with great caution. If a developer wants to add a new global style, there should probably be a meeting first or an approval process.

The files that contain your global styles should include a comment that says something like "Do not modify or add to this file without receiving approval from the solution architect."

NAMESPACES

If you've used C#, Java, or a similar programming language, you're familiar with namespaces. Namespaces solve the same basic problem. If I write a class called SomeClass and another developer writes a class called SomeClass, there will be a conflict. But if my class is in MyNamespace.SomeClass and the other class is in YourNamespace.SomeClass, there's no conflict.

With CSS, it's easy to make something like a namespace. Suppose I am working on a form where a user will enter new transactions. The first thing I will do is wrap the entire section in a <div> and give it a unique class name. That's my namespace.

<div class="newTransactionEntryForm"> 
</div>

All the CSS I write for this section will go in a file with the same name, newTransactionEntryForm.css. (If you're using SASS, it would be called newTransactionEntryForm.scss.)

All of my CSS has to be qualified by this top-level name,

.newCustomerEntryForm .submitButton {...}
.newCustomerEntryForm .selected { ... }

If you're using SASS, it's a little easier:

.newCustomerEntryForm {
    .submitButton { ... }
    .selected { ... }
}

Using this system, I don't have to worry that my .selected class will conflict with someone else's .selected class, or that the new developer hired next year will break my code.

This works nicely if you're developing with React JS or Vue or some other component or template-based system. The outer <div> on each component or template will be given a CSS class name to match the component name,

<div class="confirmSubmission">
</div>

The CSS or SASS for the component will go in a file with the same name. You might even save the CSS file in the same folder as the component. Alternatively, you could designate a folder where all the CSS files for the entire project go.

The result is that, when I want to see all the CSS that affects the appearance of my UI section/template/component, I can easily find the dedicated CSS file, and I can find the global CSS files. I shouldn't have to look at anything else. (If I'm also using a third-party CSS package such as Bootstrap, I have to look there too.)


DON'T EVER USE !important

A common thing I've seen is for developers to get frustrated when their CSS isn't working correctly and to start adding! important until it works. That causes problems for everyone else. If I comply with the system so that my CSS looks like this:

.claimEntryForm .submitButton { background-color: blue }

and my HTML is like this:

<div class="claimEntryForm">
    <button class="submitButton"></button>
</div>

and someone else writes this:

.submitButton { background-color: green}

My button is still going to be blue. CSS has a hierarchy that determines which style gets applied, and my style wins. But if the other developer adds and ! important, that overrides the normal CSS hierarchy, and my button will probably be green. The other developer has broken my code.

When one developer starts using ! important, it triggers an arms race. Other developers have to add ! important to their own CSS to make it work. The thing to do is instruct the developers never to use it ! important without permission, and to keep a lookout for its use. A code analysis tool could flag uses of! important for inspection.

NAMING SYSTEMS

There are a lot of naming conventions designed to make it easier to make CSS more maintainable. BEM ("Block Element Modifier") is a nice system.

I like BEM, but it can be very difficult to keep it going in large projects that last multiple years. Enforcing the system over a long time with developer turnover is hard. Most web developers are not familiar with BEM or any other system. Their focus is on JavaScript, with CSS as an afterthought. Compliance with the CSS system can lapse over time. A few developers stray from the system, and then the developers hired later emulate their code.

The system described here seems easier to enforce over time. A developer making a distinct UI component - a form or a section of the screen - can readily understand that it should have its own dedicated CSS file, and the file should be stored in the same place as the component. You can ask the developer to use BEM or other naming standards within the file too. But even if the developer fails to follow the standard, the file should still be small enough to understand easily.

As long as your developers follow these simple rules, you can keep your CSS from devolving into chaos,

  • Don't modify the global styles without permission
  • Wrap your components in a div with a "namespace" CSS class
  • All the CSS for the component should go in a single file stored with the component
  • Never user !important

More can be done, but if you can enforce this, you should be in good shape.