We use cookies on our website, hope you don’t mind. Just imagine a plate of delicious meringues, they look like clouds. Read more

Development

6 Steps to Make Maintainable CSS Code

Share this Article on:

Stay in touch. Subscribe to our Newsletter

6 Steps to Make Maintainable CSS Code

CSS is a fairly simple language to learn on a basic level and to kick off with the coding. But when your stylesheets start to grow, it becomes more and more difficult to untangle messed up classes.

Here I collected a couple of 10Clouds tips to help you write more manageable code. They’ll be useful no matter if you’re working on a project’s styles on your own or in a team.

For the sake of brevity, I assume that you’re already familiar with preprocessors and their concepts.

1. Modularise your styles

Begin treating your UI as a set of repeatable modules. For example, if you are writing code for a news webpage, it is possible to break up this layout for smaller components such as header with navigation, footer, article, or even the smallest building blocks, eg. buttons and links.

Preprocessors give you the power to write stylesheets separately, and then @import them into the main file. There are many ways to build a file structure for modular styles, I’ll just give you one example:

styles/
|
|-- utils/                  # Common variables, mixins
|   |-- _reset.scss         # CSS reset
|   |-- _mixins.scss
|   |-- _variables.scss
|   |-- _helpers.scss       # Helper classes, eg. for centering
|
|-- components/             # Basic building blocks
|   |-- _headers.scss       # Styles for headers
|   |-- _buttons.scss       # Styles for buttons
|   |-- _box.scss           # Styles for boxes
|   ...                     # Etc...
|
|-- modules/                # Styles for partials
|   |-- _navigation.scss    # Styles for page navigation
|   |-- _article.scss       # Styles for articles
|   ...
|
|-- pages/                  # Styles specific to pages
|   |-- _landing.scss       # Landing page styles
|   |-- _registration.scss  # Styles for registration page
|   ...
|
|-- vendor/                 # Styles from other projects (eg. plugins)
|   |-- _carousel.scss
|   ...
|
|-- main.scss               # Primary SCSS file

Note that I’ve done it progressively, composing from smallest repeatable elements like buttons, which will appear on almost every page, to styles specific for pages. You can also look how other developers did this: The Sass Way, Hugo Giraudel’s way or explore these examples.

2. Decide on a naming convention for classes

Naming things is hard I’d say, especially if you try to name CSS classes.

It’s very important to have a coherent naming convention, not only when a great deal of developers touch the code, but also when you are the only person who writes stylesheets for this project. Then you should do it for your future self (or any other person who takes it over), just like commenting code.

Your first thought could be “Let’s name things semantically!”. Yeah, it’s perfectly right! When the graphic designer changes colours, you don’t want to grep HTML files to change

.blue-box

to

.green-box

(to say the least, there could also be a hundred classes named that way). So, you decide to choose to name things like

.nav-main

instead of

.large-emerald-shiny-tabs

But don’t hold on too tightly, the main point is to take the most sensible approach about naming classes as possible – all of the selector names don’t have to be semantic. Just follow a coherent convention and don’t use names describing an element’s appearance.

If you already decided to incorporate advice from my first point then check out resources about BEM methodology, which encourages you to name things according to the idea of “Block, Element, Modifier”.

3. Deal with specificity

In case you forgot the CSS specificity concept, here is a quick recap.

In general, try to stick to this simple rule of thumb: always try to use the least specific selectors as possible. Very specific selectors, like

#main-nav > li.nav-item { background-color: #ccc; }

are hard to override. In any case, when you have to code a similar element, but with slightly different styles, you would write a more specific selector, or even be tempted to use !important. This leads straight to bloated code that is hard to maintain. I would recommend using explicit selectors for an element, like classes:

.nav-item { background-color: #ccc; }
.nav-item-modified { background-color: #000; }

It looks better, right? You should also avoid using IDs, because they are almost as specific as inline styles. They also have another drawback: they aren’t reusable, and this is something we really don’t want to have in our modular CSS.

4. Use preprocessors the right way

Preprocessors can really be a double-edged sword. They cannot guarantee you a clean, well-maintainable code if you don’t use their features properly.

Nesting rules

You should avoid nesting CSS rules, unless it’s really necessary. This is probably the most common mistake made by beginners. Follow the inception rule:

Don’t go more than four levels deep.

I’ll try to explain why it’s so important on the example:

<nav>
  <ul class="simple-menu">
    <li class="simple-menu-item"><a>Home</a></li>
    <li class="simple-menu-item"><a>About</a></li>
    <li class="simple-menu-item"><a>Blog</a></li>
  </ul>
</nav>

Seeing this it’s tempting to recreate HTML structure in styles and write in SCSS:

nav {
  .simple-menu {
    background-color: #ddd;
    
    > li.simple-menu-item {
      display: inline-block;
      border: 1px solid #eee;

      > a {
      color: #ff00ff;
      }
    }
  }
}

which compiles to:

nav .simple-menu { background-color: #ddd; }
nav .simple-menu > li.simple-menu-item { display: inline-block; border: 1px solid #eee; }
nav .simple-menu > li.simple-menu-item > a { color: #ff00ff; }

If you needed, for example a similar menu in another page, but with just a little tweaked color of the link, you’d have to override the last selector, and probably end up with this:

nav .simple-menu.modified > li.simple-menu-item > a { color: #ffff00; }

Not even this creates overly qualified selectors and causes problems with specificity. With tightly coupled HTML, it becomes hard to maintain. When abused,  it may cause performance problems and cause your stylesheets to grow in an uncontrolled manner. Overly nested rules are also less readable.

5. Avoid undoing styles

Another thing which may affect maintainability of your code is resetting styles. CSS is about inheritance, and undoing values declared in another selector makes virtually no sense.

Let’s have styles for headings:

.heading {
    font-size: 1.2em;
    margin: 0 0.5em;
    border: 1px solid #ccc;
  }

  .heading-no-border {
    margin: 0;
    border: 0;
  }

If styles are being resetted in

.header-no-border

class, why declare them for base class?

.heading

It is a badly designed code. This would be a simpler and more maintainable way:

.heading {
    font-size: 1.2em;
}

.heading-bordered {
    border: 1px solid #ccc;
    margin: 0.5em;
}

Undoing styles may be tempting when you have to deal with default styles of a framework you are using (like Bootstrap). Before including it in your project, consider choosing preprocessor version, and make changes directly in its code.

6. Document your code and create a style guide

CSS is a declarative language, so if you are using meaningful class names documenting code can seem unnecessary. But thinking about the future and other people who are or will be involved in your project, comments are an invaluable thing. Why and how to document your code is explained here in CSS guidelines, so I won’t go much into details here.

It’s worth to create your own or choose existing code guidelines, which include naming conventions, methodology used, commenting style and file structure. This will benefit all the people who ever touch the code.

Further reading

This article just scratches the surface. If you are interested in this topic, I can recommend you some excellent resources in the web, which cover the issues of modular CSS, code maintainability and various methodologies:

by Marta Sztybor, Front-end Developer

you may also like these posts

Will React Native Save You Money? A Word from a Developer

5 Novelties in PostgreSQL 10 That Will Make You a Happier Developer

Why Test-Driven Development Is Like Surgery

SUBSCRIBE TO OUR NEWSLETTER

Get the latest info about technology, design, product management (and some snaps from 10Clouds life) - subscribe to our newsletter.

Free project quote

Fill out the enquiry form and we'll get
back to you as soon as possible.


Thank you for your message!

We’ll get back to you in 24 hours.

Meanwhile take a look at our blog.

Read our blog
Gareth N. Genner Photograph

Gareth N. Genner

Co-Founder of Trust Stamp

Quote

We needed a partner who could take on our idea, and make it real. 10Clouds bring so many different skills. We feel that every member that’s involved in the project is a member of our team.