Our Approach To BEM
Matt Bailey / +Matt / May 12, 2015

BEM logo

Here at GPMD we've come a long way in the past three years, working hard at improving our techniques and methodologies. We were early adopters of Responsive Web Design, we've embraced CSS Preprocessors such as Less and Sass, and we couldn't live without task managers such as Grunt. We've also adopted certain CSS strategies such as ITCSS (Inverted Triangle CSS) to help when working with projects at scale.

Another CSS methodology that we've fully embraced with open arms is BEM (Block, Element and Modifier). It has made a huge difference to the way we work and also to the quality of our code. Our CSS has become much more modular and scalable - we've definitely reaped the benefits of this as the size and complexity of our projects has grown.

Below is an outline and some of the reasoning behind our approach to BEM.

Core Principles

We aim to write CSS that:

  • Scales - is easy to manage and maintain as a project grows
  • Is transparent - is clear and obvious in its intent
  • Is self-documenting - doesn’t require supplementary documentation

In order to achieve this we aim to keep our code modular, treating everything (where possible) as a separate component. We use a BEM ‘style’ class naming convention (i.e. we don't strictly adhere to the official BEM recommendations), which enables us to effectively encapsulate our classes’ roles and responsibilities.


Block, Element and Modifier

The Basics

/* Block - the main, outer wrapper of our component */

.block {}

/* Element - A part that makes up our Block */

.block__element {}

/* Modifier - A modification to the block */

.block--modifier {}

A Working Example

/* CSS */

.panel {} /* Block */
.panel__title {} /* Element */
.panel__content {} /* Element */
.panel--rounded {} /* Modifier */

/* HTML */

<div class="panel panel--rounded">
    <h2 class="panel__title"></h2>
    <div class="panel__content"></div>

It is immediately obvious what everything here is and does, and clearly follows the principle of transparent and self-documenting code.

Using Multiple Modifiers

It is generally considered better practice to fully declare modifiers rather than chain them (using attribute selectors in your CSS).

Fully declaring modifiers can lead to very long class attributes in your HTML, but the CSS is cleaner and clearer. Chaining modifiers leads to more concise HTML class attributes, but more complex and (potentially) less stable CSS.

Example one, full declaration:

/* CSS */

.block {}
.block--mod-one {}
.block--mod-two {}

/* HTML */

<div class="block block--mod-one block--mod-two"></div>

Example two, chaining:

/* CSS */

.block {}
.block[class*="--mod-one"] {}
.block[class*="--mod-two"] {}

/* HTML */

<div class="block--mod-one--mod-two"></div>

Modifying Elements

It is perfectly acceptable to modify Elements as well. For example:

/* CSS */

.block {}
.block__element {}
.block__element--modifier {}

/* HTML */

<div class="block">
    <div class="block__element block__element--modifier"></div>


There is also nothing wrong with verbose class names to help bring clarity to the code. For example:

/* CSS */

.information-panel {}
.information-panel--rounded-corners {}

/* HTML */

<div class="information-panel information-panel--rounded-corners"></div>

Here there can be no doubt that the panel is an ‘information’ panel, and that the corners are rounded. In the previous example one could argue that the ‘--rounded’ modifier is a little ambiguous - what is rounded?

Block Starting Context & Nesting

Something that frequently comes up is how to deal with the starting context of blocks and/or nested elements?

Harry Roberts (CSS Wizardry) states "As a rule, BEM applies to self-contained, discrete parts of the UI". To that end we try to keep our Block scope specific - it’s ok to start a new Block within a block. Not only is this easier on the eye (and therefore easier to understand), it doesn't enforce any kind of DOM structure on us.

/* CSS */

.classroom {}
.classroom__door {}
.classroom--light-on {}

.desk {}
.desk__drawer {}

.chair {}
.chair__cushion {}

/* HTML */

<div class="classroom classroom--light-on">
    <div class="classroom__door"></div>
    <div class="desk">
        <div class="desk__drawer"></div>
        <div class="chair">
            <div class="chair__cushion"></div>

Here we have three distinct Blocks (each containing Elements), clearly related, but with self-contained roles.

Incorrect Usage:

‘Nesting’ of Elements and Modifiers is generally unnecessary and should be avoided if possible. You do not need to reflect the full path to the Element as if you were traversing the DOM. For example, these would generally be considered incorrect:

.block__element {}
.block__element__element {}
.block__element__element__element {}

If nothing else they are more complex to read and therefore go against the principles of your code being clear and obvious. Instead, it’s better to examine the starting context of your Blocks and adjust the naming accordingly.

And that's the basics of our approach to BEM. If you have any comments or questions about any of the above please do feel free to leave a comment below, or contact us by email or through Twitter. Thanks for reading.

Further Reading

Some great resources on working with BEM and CSS that scales