A solution to how to name you CSS classes
Problems with naming CSS classes
I think I might not be the only one with this experience: after finally grasping all the important concepts regarding CSS I wanted to start giving what I thought would be beautiful yet simple style to my HTML code. But suddenly I ended up with class names such as “blue” “bigger” “text_normal”. “text_normal2” and similar. I stumbled directly into this CSS pitfall, which seems to be caused by a lack of structure and rules to follow when writing CSS. This kind of code is dangerous and hard to maintain because you might forget what class name does what and to which HTML element it can be applied, and so on. Chaos reigns.
So what possible solutions to this problem are there? You could come up with your own “home-made” CSS-naming set of rules to keep your code manageable but this would mean only you would be able to read the code fast and your team members would have to try and decipher your rule set. Not to say if everyone in the team made up their own CSS naming convention. Why not try an option that has been around some time know and therefor is tried and tested?
BEM – a naming convention to solve our problems
So today we will explore a popular CSS naming methodology that you may have heard about before – the BEM or Block Element Modifier methodology. It is a set of rules to follow when naming your classes, which was thought up by a known Russian technology company, Yandex. This approach seems to be quite popular among developers, so let’s see why.
First off, the list of advantages to your code when you implement BEM looks really promising:
- improved structure – you can easily tell how the HTML elements are related one to another thank to the classes names being so descriptive;
- easier readability – a big plus when working in teams;
- maintainability;
- ease of application – you do not need to do anything other than just start employing the BEM rules when naming you CSS classes and that’s it;
- reusability - thanks to BEM being so modular it can be easily moved from one project to another;
- BEM contributes to CSS specifity flatness – and this is a really good thing for maintaining a clean code and helps us to avoid having to use using the important! tag;
- it can be applied to big as well as small projects;
- strict naming rules help to prevent naming conflicts;
BEM rules
You name your CSS classes so that they reflect if they style a block, an element or if they are just their modification.
You don’t use ID selectors, only classes.
All the classes you create are “flat” - you DO NOT NEST THEM, they are single class names – in this lays the magic of BEM – the specificity level of all your style selectors will be homogeneous and the risk of style cascading issues will be lower. Example:
<article class="blog">
<h2 class="blog__title">About me</h2>
<
p class="blog__text">My life is fabulous</p>
</article>
.blog{};
.blog__title{};
.blog__text{};
all the CSS selectors above have the same specificity score of 10;
In comparison:
<article class="blog">
<h2>About me </h2>
<p> My life was fabulous</p>
</article>
.blog{};
.blog h2{};
.blog p{};
Here, the first selector has a specificity score of 10 but the other two, being combinations of class and element selectors amount to a score of 11 specificity points each.
BLOCK
- a piece of HTML markup which can work and exist on its own;
- independent from other parts;
- parent of element(s);
- can contain other blocks, but even if this kind of nesting happens, all the blocks remain equal, devoid of a hierarchical structure;
Example: header. footer, search block, etc.
Naming rules:
The block’s name should describe its purpose, (“menu”, “button”) and not its design (“small”, “pink”).
The block name must be unique within a project. If there are various instances of the same block in one project, we use the same name (like if we have two search blocks which are the same just placed differently on the page).
Also, since a block is an independent entity, its styling should not have an impact on its surroundings, so its properties like margin or position should not be set.
ELEMENT
- forms part of a block, outside of which its existence would not make sense;
- independent from other parts;
- child of a block;
- elements can be nested inside each other;
Example: input field of a form, text on a button.
Naming rules:
The element’s name should describe its purpose, (“item”, “text”) and not its design (“small”, “pink”).
The element’s full class name is created by first naming the block where it is located and then appending two underscores and its name, like this:
.block__element{};
.menu__item{};
An element can not be a part of another element. This means that naming according to the pattern “block__elem1__elem2” is not correct.
MODIFIER
- properties used to change appearance, state or behavior of blocks or elements;
- can not be used alone by itself but appended to an existing block or element;
- more than one modifier can be used at once;
- elements can be nested inside each other;
Naming rules:
The modifier name should describe appearance, state or behavior (“small”, “yellow”, “disabled”, etc.).
When appending a modifier name to a class, there are two alternative options: either you use a single underscore (block_modifier or block__element_modifier) or a double hyphen (block-- modifier or block__element -- modifier).
The single underscore variant favors us when working with XML environments, where in comments, double hyphens are not allowed.
There are two types of modifiers:
Boolean modifier– following an on/off logic, for example “focused” or “disabled”.
In this case, we just need to use one word as the modifiers name, assuming that if the modifier is present, it means that its boolean value is set to true:
<button class=”btn btn--disabled”>
Key-value modifier – when we need two words (key and value) to describe our modifier. For example:
<button class=”btn btn--color--grey”>
Modifiers can also be combined:
<button class=”btn btn--color--red btn--size--xs”>
BEM - downsides
Everything in this world seems to have its downsides, and BEM is of course no exception. Some of the most listed reasons why developers dislike it:
- ugliness of the classes names – they grow long and are full of those underscores and dashes;
- a steeper learning curve – even though the basics idea of BEM is easily understandable and seems quite logical, it takes a while to be able to deploy it correctly in your code;
- at occasions the code written using BEM turns out to be longer;
- you must have complete control over your markup code;
- it takes some experience to be able to plan your BEM classes in advance, which leads to having to refactor your code if done wrongly;
BEM CAVEATS – most common mistakes
Nested blocks or elements in class names
Many a newcomer erroneously assumes that the classes written in BEM style should mirror in a one to one fashion the structure of the HTML code. This is not true. If you try to reflect the exact same way the HTML tree is composed in your BEM code, you end up with class names that have more than one element name – this should not happen!
Example:
<header class="header">
<nav class="header__nav">
<a class="header__nav__item" href="#">Home</a>
<a class="header__nav__item" href="#">About</a>
</nav>
<img class="header__img" >
</header>
BEM classes are supposed to follow
BLOCK__ELEMENT—MODIFIER
just one block and one element and one optional modifier per class name
and not BLOCK__ELEMENT__ELEMENT--MODIFIER.
So the correct version of our previous code would be:
<header class="header">
<nav class="header__nav">
<a class="header__item" href="#">Home</a>
<a class="header__item" href="#">About</a>
</nav>
<img class="header__img">
</header>
Wrong usage of modifier
If you have a block or element which has two or more variations, you may want to create a modifier. A simple example of a modifier is a button in two color versions. So in the CSS rule where you modify the modifier, you should only change the property which is different to the main version, in our case the color, like this:
.btn {
text-align:center;
display:flex;
justify-content:center;
color: red;
}
.btn--pink{
color:pink;
}
and not:
.btn--pink{
text-align:center;
display:flex;
justify-content:center;
color: pink;
}
And then, in the mark up, you should use the modifier by combining the two classes:
<button class="btn">Red button</button>
<button class="btn btn--pink">Pink button</button>
and not:
<button class="btn">Red button</button>
<button class="btn--pink">Pink button</button>
Or in other words, the modifier class is not to be used alone, but it should complement the default class.
Combining with Bootstrap
I finally got to try and put this method in practice, I soon discovered a problem – is it compatible with Bootstrap? I am used to building pages using this framework and it would be disappointing having to sacrifice this well-known friend and helper.
After a quick search I discovered that yes, Bootstrap and BEM can be combined if you want:
<section class="container-fluid main-content"> <article class="row main-content__entry"> <h2 class="main-content__title>Title</h2> <p class=
main-content__text">Lorem ipsum…</p> </article> </section>
Site note: Bootstrap itself uses classes which kind-of resemble the BEM syntax (like btn btn-primary).
Conclusion
When I first heard of BEM I cheered - finally a system, an order into class naming. But I have to admit that my relationship with the BEM concept had its ups and downs – after the initial excitement I quickly fell into one or two BEM “traps” and had to rethink again how to design my code. But in the end I consider it a great approach to be aware of and use according to your needs. And remember: it does not have to be BEM all the time and at all costs. There are also other methodologies (like OOCSS, SMACSS, SUITCSS or the Atomic approach) to consider.
But as far as I am concerned, it is always good to be up-to-date with all the possibilities available when it comes to organizing code. Maybe after getting to know different approaches you will find a nice combination that works for you and your project.
For more information on BEM, have a look here.
Business vector created by freepik - www.freepik.comIveta Karailievova
Originally coming from a marketing background, decided to turn her life around and immerse herself into the wonderful exciting and most importantly – never boring world of technology and web development. Proud employee at MA-NO . Easily loses track of time when enjoying working on code. Big fan of Placebo, cats and pizza.