Forum

Methodology

Toolbox

Platform

Community

Frequently asked questions

Why BEM?

Blocks and elements

JavaScript

CSS

No answer found?Place your question on our forum!

How does BEM differ from OOCSS, AMCSS, SMACSS, SUITCSS?

  1. BEM is applicable to JavaScript as well as CSS.
  2. BEM has more in common with Web Components than with the CSS solutions listed. (What is the difference between BEM and Web Components?)
  3. BEM provides a comprehensive solution for creating the architecture for your project and helps organize development processes.

Find out more about the BEM methodology.

It is possible to use BEM at the CSS level only. You just need to follow the guidelines proposed by the methodology.

What is the difference between BEM and Web Components?

Browser support

Encapsulation

Template execution

Build vs HTML import

Abstraction over a DOM tree vs Custom Elements

What is the difference between BEM and Bootstrap?

In BEM terms, Bootstrap is a set of ready-made blocks. BEM, on the other hand, is not a library of interface elements but a methodology that allows you to

BEM does provide its own block library, called bem-components. Other BEM libraries are also available.

A block or an element: when should I use which?

  1. If you're dealing with a fragment of code that can be reused and does not depend on the implementation of other components of the page, you should implement it as a block.
  2. If it's a fragment of code that cannot be used on its own, without a parent entity (block), in most cases that should be an element.

This rule does not apply when implementing elements that, for reasons of simplifying the development process, have to be broken down into smaller, sub-element, parts. The BEM methodology does not recommend creating elements of elements. So, in cases like this, instead of an element, a service block should be created.

Why does BEM not recommend using elements within elements (block__elem1__elem2)?

The existence of elements of elements hinders the ability to change the internal structure of the block: elements cannot be swapped around, removed or added without modifying the existing code.

In the BEM methodology, blocks are the only entities that support nested structure (block__elem). A block name defines a namespace that ensures the dependence of elements on the block.

A block can have a nested element structure in a DOM tree.

<div class="block">
    <div class="block__elem1">
        <div class="block__elem2">
            <div class="block__elem3"></div>
        </div>
    </div>
</div>

In the BEM methodology, though, the same structure is always represented by a flat list of elements.

.block {}
.block__elem1 {}
.block__elem2 {}
.block__elem3 {}

This makes it possible to change the DOM structure of the block without modifying the code of each individual element.

<div class="block">
    <div class="block__elem1">
        <div class="block__elem2"></div>
    </div>
    <div class="block__elem3"></div>
</div>

The structure of the block changes while the rules for its elements and their names remain the same.

Why include the block name in names of modifier and element?

A block name in the names of BEM entities is used for


NB: The BEM methodology allows freedom of choice when it comes to a choosing a preferred naming strategy, however consistency of names is required. For example, the following are all valid options: context, ctx or c, attributes, attrs or as. Select one name and stick with it throughout the project.

Namespace

A block name defines a namespace and ensures unique names for elements and modifiers. This helps reduce the impact of elements and modifiers of one block on the implementation of another.

Mixes

A mix is an instance of different BEM entities being hosted on a single DOM node. When mixing a modifier, a block name indicates what block the modifier will be applied to. If a block name is not specified, the modifier will be applied to all the mixed BEM entities.

Let's say we have a mix of a menu item (menu_item) and a button (button:

<div class="menu__item button"></div>

Let's add a modifier called active in short notation (with no block name):

<div class="menu__item button active"></div>

This kind of HTML markup leaves it unclear as to whether the modifier relates to the menu item (menu__item.active) or the button (button.active). Specifying the block name (button_active) indicates the BEM entity to which the modifier will be applied.

Likewise, notation like <div class="block mod"> leaves it unclear as to what BEM entities are being used. For example, you can't tell from <div class="checkbox button"> whether it's a mix of a modifier and a block or a mix of two blocks.

The full name of the modifier <div class="block block_mod"> leaves no doubt as to the types of entities: <div class="checkbox checkbox_button">.

Code search

Explicit and unique names facilitate searching the code or the file system for specific entities.

Let's compare the results of a global search during the debugging stage. Let's find a modifier called active. If short notation is used (active), the search results will include all possible combinations and HTML fragments containing active. In the BEM-recommended notation the name of the modifier already contains a additional search parameter in the form of the block name (button_active). Because the modifier name is unique, the search will return only relevant code fragments.

How do I make global modifiers for blocks?

BEM does not accommodate the concept of global modifiers — any modifier always belongs to one specific BEM entity.

If a CSS property needs to be moved outside of a block and applied to different BEM entities in the project, a separate block should be created, implemented in the CSS technology.

BEM allows us to combine the implementation of different blocks using mixes:

<div class="block1 block2"></div>

Why create separate directories and files for every block and technology?

For the purpose of convenient development and support, the file system of a BEM project is divided into nested directories and files.

The use of the recommended file system structure is optional. You can use any alternative project structure that conforms to the principles of BEM file system organization, for example:

flex scheme

blocks/
  input/
      input_layout_horiz.css
      input_layout_vertical.css
      input__elem.css
      input.css
      input.js
  button/
blocks/
  input/
      input.css
      input.js
  button/
blocks/
  input.css
  input.js
  button.css
  button.js

flat scheme

blocks/
  input_type_search.js
  input_type_search.bemhtml
  input__box.bemhtml
  input.css
  input.js
  input.bemhtml
  button.css
  button.js
  button.bemhtml
  button.png

Why use i-bem.js when you have jQuery?

i-bem.js is a specialized framework for developing projects with JavaScript in terms of blocks, elements, and modifiers.

i-bem.js is not meant to replace any general-purpose framework, such as jQuery.

i-bem.js allows you to

Why should I avoid using nested selectors?

BEM is all about independent blocks. Nested selectors increase coupling within the code and make code reuse impossible. This is in contradiction to the BEM principles.

The BEM methodology allows nested selectors, but recommends keeping their use to a minimum.

For instance, nesting is appropriate for changing elements depending on the state of a block or its assigned theme.

.nav_hovered .nav__link
{
    text-decoration: underline;
}
.nav_theme_islands .nav__item
{
    line-height: 1.5;
}

Why does BEM advise against using combined selectors for creating CSS rules for modifiers?

Combined selectors make block redefinition more difficult because of their higher CSS specificity compared to single selectors. Combined selectors for a block modifier (.block1.mod) and for a redefined block (.block2 .block1) have the same specificity. Block redefinition would depend only on the order of rules in the declaration.

Consider an example:

<div class="header">
    <button class="button active">
</div>

The rules for the modifier active for the button are written as the combined selector .button.active. To redefine the button with the parent block header, selector .header .button is created. Both selectors have the same specificity, so the application of CSS rules is determined by their declaration order.

Using the block name in the name of a modifier gives a higher priority to CSS rules for block redefinition. The .header .button selector will be always of a higher priority than .button_active.

Reasons for including the block name in a modifier name

Can I combine a tag and a class in a selector (e.g. button.button)?

Combining a tag and a class in one selector increases its CSS specificity. Adding a modifier won't redefine the CSS rules of the block since the specificity of the block selector is higher.

Let's look at an example:

 <button class="button">

Let's use a button.button selector for the CSS rules of this block.

Now with a modifier:

 <button class="button button_active">

The .button_mod selector will not redefine CSS properties of the block with the button.button selector, as the latter has higher specificity. For the redefinition to work, the selector for the modifier needs to be combined with the tag as well: button.button_mod.

As your project keeps growing, you may have blocks with selectors like input.button, span.button and, say, a.button. Then all modifiers of the button block and all its nested elements will require four different declarations for each instance.

Why are custom tags not used for blocks in BEM?

Blocks could be represented in HTML by custom tags, with CSS rules defined for them. In that case classes would only be used for modifiers: <button class="mod"/>.

Custom tags can indeed be used for creating block selectors, but the following restrictions apply

Why cannot I use a CSS Reset?

Blocks are independent components. They must not be affected by page-wide CSS rules. Otherwise their independence is compromised and their reuse becomes problematic.

A CSS Reset is carried out using global CSS rules, which are in most cases written for tag selectors, which is not recommended practice for a BEM project.

If you must reset your styles, in BEM you can do it on a per-block basis.

Here is an example. If a menu block and a list block in your project are both represented by a <ul> tag in HTML, then each block must provide a CSS Reset for <ul>. Duplication in the resultant code can be avoided by using a CSS optimizer.

If your project does not use a CSS optimizer that combines selectors with the same sets of rules, you can use a CSS preprocessor. Then you can have a reset of rules for every new block, mixing the proper code. E.g., in SASS it would look like this:

.menu {
    @include reset-list;
}
.menu__item {
    @include reset-list-item;
}
...
.list {
    @include reset-list;
}
.list__item {
    @include reset-list-item;
}

This method is only appropriate in the absence of an optimizer.

Why cannot I write block_mod instead of block block_mod, when the modifier name already contains all the block data?

Using multiple modifiers on the same block (e.g., <div class="block_theme_christmas block_size_big">) will cause duplication of the code that implements the basic functionality (logic and styles) of the block.

Why cannot I include a CSS property name in a modifier name: .block__element_border-color_grey?

The BEM methodology recommends choosing names for modifiers based on semantics rather than visual representation.

<small>This FAQ is partially based on http://getbem.com/faq/</small>

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.