BEM methodology
In the second post of my series on the CSS methodologies we will present the most popular of them – the BEM methodology. If you want to know what CSS methodologies are and why it’s worth using them – follow this link.
What does BEM mean?
BEM is an acronym for the words Block Element Modifier, which perfectly describes the general concept of this methodology. Each application consists of Blocks (similar to approach of components in JavaScript frameworks). Those blocks create an independent part from the rest. For example, we can include a page header, menu, sidebar, footer, list or form. Inside blocks, there may also be other blocks, as long as they form an autonomous part of the page.
However, if we can extract fragments that are not independent themselves, they only make sense in the context of a parent or ancestor, we call them Elements. As examples, you can list here the list elements, menu items, and image captions.
Let’s present blocks and elements on an example:
<body>
<nav> <!-- block -->
<ul>
<li> <!-- element -->
<a href="..."> <!-- element -->
Menu link
</a>
</li>
</ul>
</nav>
<h1>Page heading</h1> <!-- block -->
<article> <!-- block -->
<header> <!-- element -->
<h2>Post title</h2> <!-- element -->
</header>
<section> <!-- element -->
<img src="..."> <!-- element (can be also a block) -->
<div>
<p></p> <!-- element -->
<p></p>
</div>
</section>
<footer> <!-- element -->
Post footer
</footer>
</article>
<footer> <!-- block -->
<ul>
<li> <!-- element -->
<a href="..."> <!-- element -->
Footer link
</a>
</li>
</ul>
</footer>
<body>
There is last word remaining – a Modifier. It describes a group of modifiers of existing blocks or elements with default styles. These can be any modifications – from size, through background colour or fonts, to positioning. What’s important, is that the modifier belongs to a specific block or element – there are no universal modifiers.
Rules
Let us present in detail the basic principles of the BEM methodology, necessary for a correct understanding of the concept.
1. We use styling using classes
The BEM methodology uses classes for styling, avoids ID selectors and directly HTML tags. There is a specific reason for this. Namely: to avoid the problem of specificity. When we start mixing styling using different selectors and nesting, we increase the specificity of the rules contained in these selectors. That’s why we only use classes and no nesting, because we can easily overwrite specific styles.
We could use ID as style selectors, but remember that we are interested in reusable and modular code – and using ID doesn’t allow us to do this. On the other hand, the use of HTML tags does not impose restrictions on the styling of only one element (unique ID). Quite opposite – by styling the marker, we will impose a style on each marker in the entire application, and we don’t want that.
2. We don’t use nesting
We don’t allow the class to be styled in a class (there is one exception I will mention at the end of this chapter). We don’t want to increase the specificity for the styles applied in the nested class. Let’s illustrate this on two examples. Bad:
.outer-class { font-size: 14px; } .outer-class .inner-class { font-size: 12px; }
and good:
.outer-class { font-size: 14px; } .inner-class { font-size: 12px; }
By following this rule, we cause the structure of the CSS file to be flat.
3. We use one naming convention
BEM methodology imposes certain rules on how to name blocks, elements and modifiers. For blocks, we can use Latin letters, numbers, dashes. The CSS classes for blocks bear the same name as the block. In the names of elements and modifiers, there may additionally be underscores. The CSS classes describing the elements are built of:
- block name
- two underscores
- name of the element,
and CSS classes built for modifiers are created by:
- name of the block / element (depending on whether it modifies a block or an element)
- two dashes
- name of the modifier.
With more complex names, two or more expressions, the role of space is assumed by a single dash. Let’s illustrate this with an example:
<article class="post">
<header class="post__header">
<h2 class="post__title">Post title</h2>
</header>
<section class="post__content">
<img class="post__image" src="...">
<div>
<p class="post__paragraph"></p>
<p class="post__paragraph"></p>
</div>
</section>
<footer class="post__footer">
Post footer
</footer>
</article>
If we would like one of the posts to be highlighted, we use a modifier:
<article class="post post--highlight">
...
</article>
It is important that the modifier name doesn’t describe a specific CSS style, but it has a specific meaning. For example, if we want to add a dark theme to a block or element, then we create for it a semantic name
block__elem–dark-theme
instead of
block__elem–background-black
The reasons for this should be seen in the fact that the future modification of a style entails the obligation to change the name of the class – not only in the CSS file, but also in the HTML file.
There are also other variants of name creation:
block–element__modifier
block__element_modifier
b-block__element–modifier
However, they are less frequently used.
4. An exception to the rule of not nesting
It concerns a situation when the modifier changes the styles of the block that has elements. In accordance with the fact that the elements do not exist independently of the block, it is logical that modifications to the appearance of the block may affect the appearance of its elements. Instead of creating two or more classes of a given modifier in this situation (for the block and for elements), we can build one class for the block and nest element classes in it. Let’s illustrate this in two correct examples. Version with maintaining a flat structure:
.post--highlight {} .post__header--highlight {} .post__title--highlight {} .post__image--highlight {} .post__content--highlight {} .post__paragraph--highlight {} .post__footer--highlight {}
Version with nesting:
.post--highlight .post__header {} .post--highlight .post__title {} .post--highlight .post__image {} .post--highlight .post__content {} .post--highlight .post__paragraph {} .post--highlight .post__footer {}
Summary*
In this entry, we learned the BEM methodology. The general concept, naming and principles of application. The next entry will contain the Object Oriented CSS. If you want to go deeper into the ins and outs of this methodology, follow those links:
*In the summaries of the methodology entries, I omit the presentation of their advantages and disadvantages, because I want to leave each of you the opportunity to evaluate independently.
Software Developer at Aspire Systems Poland. He began his adventure with Angular in the summer of 2018. In his free time, he learns the secrets of Vue, RxJS and TypeScript. Enthusiast of sport (most of all running) and speedway.