Even if CSS is not a difficult language to learn, it is sometimes complicated to maintain an understandable and performing code on the long term or on large projects in collaboration with one or several developers.
This is where the BEM methodology becomes interesting.
What does BEM stands for?
BEM is the acronym for Block
Element
Modifier
. It is a modular approach to web development that consists in dividing an interface into several independent blocks. This naming convention can be applied to CSS classes, which allows to have a more readable and better organized code by following some simple rules.
The goal is that other developers can easily understand the structure of a component just by reading the class names. It has never been easy to name your classes in CSS and it is even more complicated for another developer to understand what they do.
Block
block
represents the main element. It is the parent component of one or more elements. (Example: header, nav, footer, etc.)
.block {}
Element
element
is a child of block
. (Example: a navigation item, a title, a paragraph, etc.) All classes start with the name of the main component block
followed by 2 underscores and the name of the element.
.block__element {}
Modifier
modifier
represents a different state or version of block
or element
. (Example: the active state of an element or a color change of an element on a specific page). It is delimited by 2 hyphens.
.block--modifier {}
.block__element--modifier {}
In practice
The BEM methodology is interesting for structuring these CSS files, but not only. Where we really find its power is in the HTML. Just by reading the different classes, we can directly understand the structure of a component and the relationship between the classes.
Let's take the example of a navigation component with several items, one of which will be styled differently with a class active
.
HTML
We can clearly see which classes are linked to the parent block .nav and which are not.
By prefixing the elements with the name of the parent block, I know that .nav__item is part of the .nav component and cannot be used outside of this block. So I can change its style with the certainty that I'm not changing other elements that are elsewhere in the code. This would not be the case if I decide to modify the .link class, which is a more global class and could also be in another component.
CSS
Performance
The BEM methodology does not only have an impact on the organization and readability of the code, but also on the performance of the site and the display time of a page. With the power of today's browsers, this is no longer a small detail, but it is important to understand how it works.
For the example, let's go back to our navigation. If I wanted to style the navigation items, I could have written it like this:
nav ul li {}
This should be avoided as much as possible for performance and flexibility reasons. The longer a selector is (targeting level), the longer it will take the browser to find the elements in the DOM. A browser reads CSS classes from the right (child) to the left (parent).
In this case it will :
- search for all the
li
who are in the DOM - then it will check if these
li sont dans un ul
- to finally see if this
ul
is in an element of typenav
This is not a good way to proceed. On larger projects, this will have an impact on the display time.
The best approach is therefore to use a methodology such as BEM, which allows to target the element directly, while knowing visually that this element is in the component .nav
.
.nav__item {}
Conclusion
The BEM methodology gives the CSS code a solid structure that remains simple and understandable.
The CSS style of an element will always remain within a component and will never depend on another element of the site. Therefore, you will never encounter any cascading problems in CSS.
Creating independent components and reusing them intelligently reduces the amount of CSS code. A code that will be easier to maintain on the long term or on large projects. By structuring your files correctly, you can create libraries of components to reuse them and even import them into other projects.
Sources