When working with open-source technologies and software, it is even more important to simplify the effort needed to read and understand your code. A good naming convention helps you solve larger problems rather than focusing on syntax and style preferences during code reviews. Seasoned developers understand the significance of well-written and organized code when working with larger websites with tons of style elements.

BEM (Block, Element, Modifier) methodology is a widely used naming convention for CSS classes that is gaining popularity because of the ease of use it offers. The fundamental concept of BEM is component-based web development. BEM makes interface development easy and fast, especially when you’re handling large projects with complex UI. Let’s explore more on BEM and how it can work with the Drupal Emulsify Twig module.

bem

What is BEM

The BEM methodology was introduced to help make CSS classes easier to access, understand and scale. It can accelerate the development process and helps build reusable components.

BEM includes three parts:

  1. Block
  2. Element 
  3. Modifier

Block

Blocks are the outermost and functionally independent component and are reusable. Examples: header, footer, sidebar, menu, content, etc.

Features:

  • Block names should always reflect the block's purpose. 
  • Blocks should not use margin or position. If you need to add margin or position then you need to apply it to the inner containers.
  • Don’t use CSS tags or ID selectors when using BEM.

Example:

<div class=”icon-button”></div>

Element

Elements are child items of a Block. Each element can have only one block and cannot be used outside of it. Examples: menu items, list items, input field, etc.

Features:

  • The element name (class) should describe its purpose (title, caption) and not its state (small/red). 
  • The element and block are separated with a double underscore (__). Like this: block-name__element-name.

Example:

  <!-- `div` outer container as `icon-button` block →
   <div class=”icon-button”>
       <!-- `div` element in the `icon-button` block →
       <div class=”icon-button__icon”>Icon Image</div>
   </div>

Modifier

A class name through which you can define the appearance, state, or behavior of a block or element. Examples: red, large, disabled, fixed, etc.

Features:

  • The modifier name describes its appearance. For example, if the appearance is “_large”, then the modifier class will be as icon-button__title_large.
  • The modifier is separated from the block or element by a single underscore (_).

Example:

<!-- `div` outer container as `icon-button` block →
   <div class=”icon-button”>
       <!-- `div` element with modifier in the `icon-button` block →
       <div class=”icon-button__icon_large”>Icon Image</div>
   </div>

Types of modifiers

1. Boolean

You can check the condition of the boolean value and set it in a variable. This variable can pass as a modifier value.

2. Key-value

The structure of the modifier's full name with key-value will follow one of these patterns:

  1. block-name_modifier-name_modifier-value
  2. block-name__element-name_modifier-name_modifier-value

Naming Conventions: Rules and Schemes

There are different naming schemes. All schemes have some common rules like:

  • Names are written in lowercase Latin letters.
  • Words are separated by a hyphen (-).

1. Classic Naming Schemes

The classic naming scheme is the default naming scheme of BEM.

Block-name__elem-name_mod-name_mod-val

  • The element name and the block name are separated by a double underscore (__).
  • The modifier name and the block or element name are separated by a single underscore (_).
  • The modifier value and modifier name are separated by a single underscore (_).

2. Two Dashes Naming style

block-name__elem-name--mod-name--mod-val

  • The element and block name are separated by a double underscore (__).
  • The block and element are separated with a modifier by a double hyphen (--).
  • The value of a modifier and modifier are separated by a double hyphen (--).

3. CamelCase Naming Style

blockName-elemName_modName_modVal

  • Each word after the first word begins with an uppercase letter.
  • Blocks, elements, and modifiers are used the same way as in the standard naming scheme.

4. React Naming Style

BlockName-ElemName_modName_modVal

  • Block's name and element’s names begin with an uppercase letter. 
  • The modifier’s name begins with a lowercase letter.
  • An element name and the block name are separated by a single hyphen (-).
  • Names and values of modifiers are separated the same way as in the standard scheme.

BEM in Drupal with Emulsify Twig module

In Drupal, we can use the BEM Twig function with the help of the Emulsify Twig module. The BEM function lets you create BEM classes on elements in the components. Below mentioned are some BEM Twig extensions and their usage.

1. Simple block name (required argument):

<div {{ bem('icon') }}>

This creates:

<div class="icon">

2. Block with modifiers:

If you want to add multiple modifiers, you can do so using an array.

<div {{ bem('icon', ['small', 'red']) }}>

This creates:

<div class="icon icon-–small icon-–red">

3. Element with modifiers and blockname (optional):

<div {{ bem('icon', ['small', 'red'], 'icon-button') }}>

This creates:

<div class="icon-button__icon icon-button__icon--small icon-button__icon--red">

4. Element with blockname, but no modifiers (optional):

<div {{ bem('icon', '', 'icon-button') }}>

This creates:

<div class="icon-button__icon">

5. Element with blockname, modifiers and extra classes:

<div {{ bem('icon', ['small', 'red'], 'icon-button', ['js-click', 'something-else']) }}>

This creates:

<div class="icon-button__icon icon-button__icon--small icon-button__icon--red js-click something-else">

6. Element with extra classes only (optional):

<div {{ bem('icon', '', '', ['js-click']) }}>

This creates:

<div class="icon js-click">

Add Attributes Twig Extension

The Add attributes Twig function allows you to add HTML attributes to the elements of your components. Take a look at some Add Attributes functions below:

{% set additional_attributes = {
  "class": ["icon-button", "icon-button__title"]
} %}
<div {{ add_attributes(additional_attributes) }} ></div>

{% set additional_attributes = {
  "class": bem("icon", ["small", "red"], "icon-button"),
} %}
<div {{ add_attributes(additional_attributes) }}></div>

Final Thoughts

BEM methodology is extremely useful to developers who want to write and maintain better quality code that can be easy to be handed over and understood. Every element has a purpose which can be easily identified by its name and which block it is coming from. When used right, you will see that using BEM can boost development speed. If you liked what you read, sign up for our weekly newsletter where we'll send you fresh, piping-hot insight right to your inbox!

Contact us

LET'S DISCUSS YOUR IDEAS. 
WE'D LOVE TO HEAR FROM YOU.

CONTACT US