8 rules to organize your CSS code

Writing CSS code is not as easy as it seems. Without some writing rules, we can quickly find ourselves with a code that is difficult to read and difficult to debug. Here is a non-exhaustive list of best practices and rules that will help you create and maintain a clear and extensible CSS style sheet.

1 - Segment CSS into multiple files

It is best to separate its CSS code into several files each corresponding to a module, a view or a page of your application. It's up to you to choose how to cut your style sheet. Cutting into files makes it easier to navigate when expanding, modifying or creating new declarations.
For example, for WordPress, it may be wise to split your code by content template.
  • page.css
  • single.css
  • header.css
  • footer.css
  • archive.css
  • template-custompage.css
The advantage of cutting CSS into multiple files and multiply especially if you use a preprocessor CSS ( Sass or Less ).

2 - Establish a Naming Convention

It is important to have a naming convention for your elements.
If there is a block in your application that contains secondary navigation, you can give it a class named ".secondary-nav" or ".nav-secondary" or ".navSecondary" or ".Nav_Secondary".
There are many recommendations on what is the best way to name these blocks, but I will not give you recommendations, just choose a standard and stick to the whole application. However, if you choose to follow the BEM methodology, then some of the examples listed above should be avoided.

3 - Use BEM (Block, Element, Modify)

BEM is a naming methodology that tends to split the entities of your page into blocks and elements.
To make it simple A page can contain several blocks, each of these blocks can contain one or more elements of its own. Finally, each of these elements can have a state which is modified according to an event or action of the user, it is to modify it.
For example, a web page is composed of 4 blocks:
  • Navigation
  • Main Content
  • SideBar
  • Footer
The sidebar is composed of different elements:
  • title
  • List of last articles
  • List of last comments
The "List of last articles" element can have several states:
  • Hide
  • Visible
We have just cut our page according to the BEM methodology applied to the CSS.

4 - Using Object-Oriented CSS (OOCSS)

It is about cutting classes by trying to respect the logic of object-oriented development that we encounter in programming languages ​​such as PHP.
Take the example of a red and green button:
.boutonRouge
{
display: block;
font-size: 12px;
color: red;
border: 1px solid red;
}

.boutonVert
{
display: block;
font-size: 12px;
color: red;
border: 1px solid red;
}

In these two examples, there is a code repetition, we will rather try to group the properties that these buttons share. Then create an additional class corresponding to their respective specificities.
.button
{
display: block;
font-size: 12px;
border-width: 1px;
border-style: solid;
border-color: transparent;
}
.bouton red
{
border-color: red;
color: red;
}
.bouton green
{
border-color: green;
color: green;
}
In HTML, the button will be called as follows:
<div class = "red button"> Red button </ div>

Classrooms are coexisting side by side. The interest is to keep a basic consistency for all button elements, they are overloaded if necessary with an additional class that extends the properties of the button, in our case, we add a border color and a text color.

5 - Understanding the Open / Closed Principle

This principle goes hand in hand with the example approach in the previous point.
When choosing an OOCSS approach, one must always remember this simple principle:
The CSS code must be extensible (open to any extension) but not modifiable (closed to any modification).
Following the example of the button:
.button
{
display: block;
font-size: 12px;
border-width: 1px;
border-style: solid;
border-color: transparent;
}

And that I created a class for a secondary button:
.bouton secondary
{
display: inline-block;
font-size: 10px;
border-width: 0;
border-style: none;
}

HTML:
<div class = "button-sub-button"> Sub-button </ div>

We notice that the secondary-secondary class modifies the display, font-size and border-width properties of the button class. We, therefore, lose the interest of the extension because we just modify and not extend properties. It would have been simpler to create a new secondary-button class by removing the border-width and border-style declarations and using this class independently.

6 - Take into account portability and quasi-skilled selectors

Portability makes it possible to reduce the dependence of our classes on HTML tags for example. Let's take a simple example:
a.bouton
{
...
}

The button class is declared but can only be used with a <a> tag. If you want to use the button class with a <div> tag, this is no longer possible.
You must, therefore, remove the reference to the HTML tag. If we want to help reading the code and explain that the button class is best used with a <a> tag then we could write the class as follows:
/*at*/
.button
{
...
}

The tag is passed in the comment but it can be used on any type of tag. This is called a quasi-qualified selector.

7 - Understanding the specificity

The specificity determines which CSS rule is applied by the browser. There is a hierarchy not necessarily intuitive in the order of application of CSS rules.
Keep in mind that any selector must be declared with the least possible specificity.
Prefer:
.myclass
{}

rather :
body.page .content .sidebar>
.myclass
{}

This will save you in most cases from dealing with conflicts related to CSS specificity.
Nesting or Nesting
The nesting of CSS classes has been introduced by languages ​​such as Sass and Less.
Nesting has obvious advantages when writing the code but generates a CSS code that is sometimes too specific (see the previous point).
We must try to have the minimum of nesting. The fewer selectors, the better. So we will have less bad surprises.

8 - Being DRY

This is a principle that aims to reduce the amount of written code and consolidate statements into duplicate.
It must be applied if two declarations very often coexist together. The DRY principle can be very useful when one codes in Less or Sass.
Example:
.text-error
{
font-size: 15px;
background-color: #ccc;
border-color: red;
color: red;
}
.A-error
{
width: 250px;
height: 250px;
background-color: # 000;
font-size: 17px;
border-color: red;
color: red;
}

We see that both classes share border-color and color properties. We can consider what are always together for a certain number of classes. So we can create a mixin and the following classes:
@mixin error-base ()
{
border-color: red;
color: red;
}
.text-error
{
font-size: 15px;
background-color: #ccc;
@include error-base ();
}
.A-error
{
width: 250px;
height: 250px;
background-color: # 000;
font-size: 17px;
@include error-base ();
}

We gained readability and refactored our code to avoid repetition.

Conclusion

Here is a set of best practices that can lay a solid foundation for writing a readable and extensible CSS code.
Not all projects lend themselves to this type of rule. For example, when it is necessary to stylize a WordPress theme and a plugin like WooCommerce, the CSS naming rules are not necessarily homogeneous and it can be difficult to implement these good practices.
This post was largely inspired by the very relevant guidelin.es which addresses more points. As always, you are free to follow them and adapt them to your projects.

Comments

Popular posts from this blog

What is a blog anyway?

The WordPress developer