The article has been originally posted on my Polish blog — devszczepaniak.pl.

At the beginning of my adventure with programming, I didn’t take care of the quality of a CSS code I wrote. All the code was included in one, bloated file. Although class names ( usually ) were quite descriptive, there was a noticeable lack of consistency and order. After getting back to this code after some time it was challenging to twig to about class names meaning. For example, a .page-header didn’t say whether it’s the main page header or an article header. In this particular case, the class name is too generic.

An example of a bad code

.name-item {
height: 100%;
}
.name-item > h1 > small {
display: block;
text-align: center;
padding-bottom: 30px;
padding-top: 1vmin;
color: rgba(0,0,0,0.4);
font-size: 3vmin;
}
.projects-container {
img {
padding:3vmin;
transition:0.4s all;
}
img:hover {
transform: scale( 0.9 );
}
}
.text-justify {
box-sizing:border-box;
font-size: 1.6vmax;
}
.blog {
font-size:2rem;
color:#4d4646;
}

Now let’s consider what is wrong with this code:

  • At first, classes’ names are not descriptive enough and misleading. The names like .name-item or .blog says absolutely nothing about a styled element meaning. Whether the elements are headers, containers or list items, or maybe some block of text? It is neither clear nor consistent.
  • The worse situation is with the .text-justify class. This class doesn't justify the text! Even worse, this class adds another, not related styles!
  • I have also paid attention to the .project-container class. The problem is not with the class name itself but with the nested elements. I assume it is a container that includes some projects. Probably the element includes a list of projects with attached images. If we assume that the container includes only images the following code is acceptable.
    However, let’s imagine a situation when we’d like to add a banner with some ads. In this case, all images ( also in the banner ) will be styled identically. For this reason, banner and thumbnails should be distinguished and img styles should be replaced with some class, for example .project-thumbnail.
  • I also try to avoid adding styles on ids and elements and style elements by using classes. However, I want to emphasize that it’s my personal practice.
  • The next aspect where there’s a noticeable lack of consistency is a color notation. Once the notation rgba(0,0,0,0.4) is used but later also another one (#4d4646) is in use. Mixing conventions is a bad practice. It is another example of inconsistency.
    The best solution, in this case, could be extracting colors to variables and base on them. Currently, variables are available even with pure CSS, so I don't see any contraindications to use them.
  • The last point I paid attention to is the .text-justify class again. Personally, I’m not a fan of classes like .font-bold, .align-center, and so on. In my opinion, a class should describe what element is, not how it looks.
    However, the most of UI frameworks and libraries like Boostrap offer such classes so as you can see there are various approaches. So the decision is up to you, I won’t judge you 😉

Specificity

For sure, the most unique in our codebase are ids. On a website, only one element can have a particular id (so it’s the most specific). The next are classes and elements. I think it is pretty intuitive.

To check and calculate specificity you can use some online tools like this one.

Let’s analyze the following code example:

<style>
#square {
background-color: black;
}
.square {
background-color: pink;
}
div {
width: 100px;
height: 100px;
background-color: orange;
}
</style>
<div class="square" id="square" style="background-color: purple;"> </div>

After running this code in the browser we will see… a purple square. It is obviously caused by inline styles on the element. You should avoid inline styles. I use inline styles only for some unusual cases like dynamically loaded background images (but also this can be achieved without inline styles).

Now let’s focus on the style tag. When we remove inline styles, our square will become black, which may be at first glance a bit confusing. But why?

The answer is previously mentioned specificity. Styles for ids have higher priority than styles for classes and elements. Although the styles for color are redefined times more, these redefinitions are ignored because of the specificity mechanism. If we remove styles for the#square id, the square will become pink. It is caused by the specificity mechanism too. Classes are higher in the hierarchy than elements. Note that in the case of an equal level of specificity the last defined value will be used:

#square {
background-color: black;
}
#square {
background-color: red;
}

In this particular case, the square will become red.

To understand the specificity mechanism better just use the example from the article and modify it a little bit. You can also use the online tool I linked earlier.

Splitting the code

However, the number of files doesn't matter. If you use tools like Webpack you don’t have to care about it. Finally, all CSS code will be minified and merged into one file.

CSS standardized methods

  • Object-Oriented CSS (OOCSS)
  • Atomic CSS (ACSS)
  • Atomic Design
  • SUIT CSS
  • Scalable and Modular Architecture for CSS (SMACSS)
  • Block Element Modifier (BEM)

Of course, there are much more standardized methods but these are the most popular. Personally, I use BEM. It’s the most convenient for me and it matches my requirements best.

The example of BEM use

The whole form needs to be wrapped in a container. Let’s add a .login-form class. This will be our block (B).

The next step will be adding a class for inputs. Let’s create a .login_form__field and use it for each input element. The crucial part of this class name is the double underscore determining elements (E) in BEM.

Every form should have some validation. For example, in the case of an invalid email or password, the invalid input should be marked somehow (for example by a red border). The responsible class for it can be called .login-form__field--invalid. The part after the double dash is called a modifier (M).

As you can see, BEM enforces some name convention. It is not only helpful during modifications, updates, adding new parts of the website, and so on, but also it creates some abstraction for the DOM structure. Now the website is not just a mix of divs and spans but a logical structure with distinguished elements like forms, toolbars, sidebars, menus, sliders, etc..

The summary

I know that I didn’t fully cover the topic. For sure really helpful are CSS preprocessors like LESS or SASS. They offer much more than pure CSS, for example. functions, loops, mixins, or conditionals. But the knowledge that I shared with you in this article is a good point to start the process of polishing your CSS code! 😉