Forum

Methodology

Toolbox

Platform

Community

Naming convention

Working with BEM entities requires a knowledge of their naming rules.

The main idea of the naming convention is to make the names of CSS selectors as informative and clear as possible. This will help make code development and debugging easier, and it also solves some of the problems faced by web developers.

Let's say we have a CSS selector named menuitemvisible. A quick view of such a notation doesn't allow us to identify types of BEM entities from the name of the selector.

We can add a delimiter, or use a capital letter to start each word inside a phrase (classical CamelCase):

  • menu-item-visible
  • menuItemVisible.

Written like this, the name of the selector is clearly divided into logical parts.

We can assume that:

  • menu is a block,
  • item is an element,
  • visible is a modifier.

However, real-life examples are often more complicated and not as straightforward, and that’s where the BEM naming convention for CSS selectors comes in useful.

A number of alternative naming schemes based on the BEM principles also exist in the world of web development.

CSS selector naming convention

  • Names of BEM entities are written using numbers and lowercase Latin characters.
  • Individual words within names are separated by a hyphen (-).
  • Information about the names of blocks, elements, and modifiers is stored using CSS classes.

Naming rules for:

Block name

A block name follows the block-name scheme and defines a namespace for elements and modifiers.

Various prefixes are sometimes added to block names.

Our experience of using prefixes is covered in detail in the article The History of BEM.

Example

menu

lang-switcher

HTML

<div class="menu">...</div>

CSS

.menu { color: red; }

Element name

The namespace defined by the name of a block identifies an element as belonging to the block. The element name is separated from the block name with a double underscore (__).

The full name of an element is created using this scheme:

block-name__elem-name

If a block has several identical elements, such as in the case of menu items, all of them will have the same name menu__item.

Important! The BEM methodology does not allow for elements of elements.

Example

menu__item

lang-switcher__lang-icon

HTML

<div class="menu">
  ...
  <span class="menu__item"></span>
</div>

CSS

.menu__item { color: red; }

Modifier name

The namespace defined by the name of a block identifies a modifier as belonging to that block or its element. The modifier name is separated from the block or element name by a single underscore (_).

The full name of a modifier is created using the scheme:

  • For boolean modifiers — owner-name_mod-name.
  • For key-value modifiers — owner-name_mod-name_mod-val.

Important! In the BEM methodology, a modifier cannot be used outside of the context of its owner.

Block modifier

  • Boolean modifier.

    The value is not specified for this type of modifier. The full name is created using the scheme: block-name_mod-name.

    Example

    menu_hidden

  • Key-value modifier.

    The value of the modifier is separated from its name by a single underscore (_) The full name is created using the scheme: block-name_mod-name_mod-val.

    Example

    menu_theme_islands

    HTML

    <div class="menu menu_hidden">...</div>
    <div class="menu menu_theme_islands">...</div>
    
    

    Incorrect notation

    <div class="menu_hidden">...</div>
    

    Here the notation is missing the block that is affected by the modifier.

    CSS

    .menu_hidden { display: none }
    .menu_theme_islands { color: green; }
    
    

Element modifier

  • Boolean modifier.

    The value is not specified for this type of modifier. The full name is created using the scheme: block-name__elem-name_mod-name.

    Example

    menu__item_visible

  • Key-value modifier.

    The value of the modifier is separated from its name by a single underscore (_). The full name is created using the scheme: block-name__elem-name_mod-name_mod-val.

    Example

    menu__item_type_radio

    HTML

    <div class="menu">
      ...
      <span class="menu__item menu__item_visible menu__item_type_radio">...</span>
    </div>
    
    

    CSS

    .menu__item_type_radio { color: blue; }
    

Example of using the naming convention

The implementation of an authorization form in HTML and CSS:

HTML

<form class="form form_login form_theme_forest">
  <input class="form__input">
  <input class="form__submit form__submit_disabled">
</form>

CSS

.form {}
.form_theme_forest {}
.form_login {}
.form__input {}
.form__submit {}
.form__submit_disabled {}

Alternative naming schemes

There are several alternative solutions that are based on the BEM naming convention.

Two Dashes style

block-name__elem-name--mod-name

  • Names are written in lower case.
  • Words within the names of BEM entities are separated by a hyphen (-).
  • An element name is separated from a block name by a double underscore (__).
  • Boolean modifiers are delimited by double hyphens (--).
  • Key-value type modifiers are not used.

Important! A double hyphen inside a comment (--) is interpreted as part of the comment, which causes an error during document validation. HTML5 Specification.

CamelCase style

MyBlock__SomeElem_modName_modVal

This style differs from the traditional CamelCase in that it uses additional underscores for separating the names of BEM entities.

"Sans underscore" style

blockName-elemName--modName--modVal

  • Names are written in CamelCase.
  • An element name is separated from a block name by a single hyphen (-).
  • Modifiers are delimited by double hyphens (--).
  • The value of a modifier is separated from its name by a double hyphen (--).

Important! A double hyphen inside a comment (--) is interpreted as part of the comment, which causes an error during document validation. HTML5 Specification

No Namespace style

_available

This style is characterized by the absence of a block or element name before a modifier. This scheme limits the use of mixes, because it makes it impossible to determine which block or element a modifier belongs to.

Which style to choose

The BEM methodology offers general principles for naming BEM entities. The choice of a particular naming scheme depends on your project requirements and personal preferences. One considerable advantage of using the naming convention offered by the methodology is the existence of ready-made development tools that are specifically geared towards the "classic naming".

In addition, the BEM methodology is not limited in its scope to the HTML and CSS technologies that are discussed in this document. The concepts of blocks, elements, and modifiers are used when working with the JavaScript, templates and file structure of a BEM project. The bem-naming tool enables you to use the same names for BEM entities in any implementation technologies that you may be using.

By default, bem-naming is configured to use the naming convention according to the methodology, but it allows you to add rules so you can use alternative schemes.

If you notice a mistake or want something to supplement the article, you can always write to us at GitHub, or correct an article using prose.io.