# BEM Methodology

## Summary


When updating web/mobile user interfaces, frontend developers often worry about breaking existing code or introducing inconsistencies. Selecting elements on a UI is often problematic because of long cascading rules, nested styles, rules that are unnecessarily high in specificity, and naming everything in the global namespace. BEM provides a modular approach to solve these problems.

BEM is a methodology, an approach and a naming convention to write better CSS styling and achieve consistent JS behaviour. **BEM** stands for *Block*, *Element* and *Modifier*. These three are called **BEM Entities**. 

BEM is not a W3C standard but it's recommended by those who have adopted it and reaped its benefits. Among its adopters are Yandex, Google, BBC, Alfa Bank, and BuzzFeed. BEM also works nicely with CSS languages (Sass, etc.), and frontend frameworks (React, etc.).

## Discussion

### Could you explain BEM with an example?

BEM is a component-based approach to design a user interface for the web/mobile. For example, we can identify components such as header, menu, logo, search and login on a typical web page. In BEM, we call these components **blocks**, each having a well-defined purpose or semantics. It's also apparent that a block can contain other blocks within it. However, each block is also independent of other blocks and can be reused elsewhere. For example, it's not necessary that the login block must be part of the header block. It could be moved to a sidebar in a redesigned page layout. 

Blocks can also contain **elements** that cannot exist outside their parent blocks. For example, a menu block is composed of menu items, each of which is an element in BEM terminology. 

Finally, an element within a block can be selectively modified depending on the context. For example, in a menu block, the active menu item could be styled differently. This modification is done using **modifiers**. Modifiers are optional. 


### What are the advantages of adopting the BEM methodology?

BEM enables flexible maintainable code. Components can be reused. Code becomes more consistent since the rules are clear. It's easier to scale to large projects. Teamwork is easier because everyone is familiar with BEM conventions. Since the approach is based on independent blocks, work can be clearly partitioned, with each team member working on a different block.

More specifically, every BEM CSS class is unique and self-sufficient. BEM doesn't need nesting of styles. We don't need long and inefficient selectors to match specific elements. BEM avoids name collisions due to its consistent naming convention. The naming convention also makes the CSS self-documenting: the relationships among DOM nodes is easier to see. DOM nodes are selected more efficiently with managed specificity. 


### What's the default naming conventions followed in BEM?

Let's consider the following: `block-name&lowbar;&lowbar;elem-name_mod-name_mod-val`. We note that names are all in lowercase, underscores are used as separators between BEM entities, and hyphens are used within names for better readability. We use double underscore to separate block from element; single underscore to separate block/element name from its modifier; single underscore to separate modifier name and modifier value.

Consider these examples: 

    + `main-menu_hidden`: main-menu is the block, hidden is the modifier.
    + `menu_theme_islands`: menu is the block, theme is the modifier, islands is the theme being specified (modifier value).
    + `menu&lowbar;&lowbar;item_type_radio`: menu is the block, item is its element, type is item's modifier, radio is the modifier's value.
    + `main-menu&lowbar;&lowbar;item_black-listed`: main-menu is the block, item is its element, black-listed is item's modifier.

### What other naming conventions are common in the BEM community?

While there's a default naming convention in BEM, you can create your own convention. Most importantly, the convention should clearly separate blocks, elements and modifiers. Other than the default one, the following conventions are used in the BEM community: 

    + **Two Dashes**: `block-name&lowbar;&lowbar;elem-name--mod-name--mod-val`: double hyphens are used between elements, modifiers and values.
    + **CamelCase**: `blockName-elemName_modName_modVal`
    + **React**: `BlockName-ElemName_modName_modVal`
    + **No Namespace**: `_modname`: no reference to block or element and hence of limited usefulness.

### What technologies assist in implementing BEM?

A block is not just about CSS. It encapsulates behaviour (JavaScript), templates, styles (CSS), documentation, and other implementation technologies. Developers can adopt any implementation technology of their choice. As a sample, we note the following: 

    + **Styling**: CSS, Stylus, Sass
    + **Behaviour**: JavaScript, CoffeeScript
    + **Templates**: BEMHTML, BH, Pug, Handlebars, XSL
    + **Documentation**: Markdown, Wiki, XML

### Could you share some BEM best practices?

An important principle of BEM is to avoid selectors based on ID or tag name. Only class names are used, and these can be reused easily regardless of the tag. It's also allowed to use multiple BEM entities on the same DOM node. 

We can use nesting in BEM but it's not recommended. Nesting increasing code coupling and inhibits reuse. Likewise, combined selectors (eg. `.btn.btn_error`) are not recommended. 

Use only a single double underscore in a name: `c-card&lowbar;_img` rather than `c-card&lowbar;&lowbar;body_&lowbar;img`. Use namespaces to improve readability: `c-` for component, `l-` for layout, `h-` for helpers, `is-` or `has-` for states , `js-` for JavaScript hooks. 

External geometry and positioning (such as padding) should be done on parent node so that the current block can be reused elsewhere. Use **mixes** to apply the same style to multiple DOM nodes. This approach is better than using group selectors. 

Take an object-oriented approach to design. Design in terms of reusable blocks. Use principles such as single responsibility principle and open/closed principle. Don't repeat yourself (DRY). Prefer composition over inheritance. Organize your files into a clear folder structure. 


### What are some criticisms of BEM?

Since BEM avoids the use of IDs or tag names, class names have to be unique. Giving these names can be a difficult task. Long class names bloat markup. To reuse UI components, we need to explicitly extend them. 

As an example, a modifier will need its own class name but giving names for each DOM node that needs to be styled with this modifier can be cumbersome. An alternative is to use utility classes, named with `u-` prefix. The trade-off is that this will result in nested CSS. Thus, a DOM node is selected as `menu&lowbar;_item u-active` rather than `menu_&lowbar;item-active`. 

Since DOM nodes are marked with BEM entities, BEM creates a semantic overlay on the DOM. This is called **BEM Tree**. While some regard this as a useful thing, others claim that BEM unnecessarily makes the markup semantic. 

## Milestones

Dec  
1996

The first version of **Cascading Style Sheets (CSS)** comes out as a W3C Recommendation. The idea of having style sheets can be traced to Tim Berners-Lee, who used it in his NeXT browser (1990), and Pei Wei's Viola browser (1992). Håkon Wium Lie released an initial draft in October 1994. 

2006

At Yandex, developers find that for large projects, layouts are becoming difficult to maintain. Long cascading rules and dependencies cause changes in one web page to affect many others. To solve this, they introduce the concept of **blocks**. A block is part of a page or layout defined semantically or visually. A block is given a unique CSS class name. Nodes within blocks are called **elements**. For example, logo is an element with a header block. 

2007

Block names use prefixes to emulate namespaces. Each prefix has its own semantics: `b-` for blocks, `h-` for block wrappers, `l-` for layouts, `g-` for global styles. This is also when **modifiers** are introduced to indicate block state or property. Modification can be context-dependent such as location; or context-independent. 

Mar  
2008

With the release of Lego 2.0, the unified styling framework at Yandex, **BEM** is formally born. Blocks are primary units. A block can be used anywhere on the page. Each block is stored in a separate folder with its own documentation. Blocks used are noted in XML files and used to generate CSS files. 

2009

Folks at Yandex invent **Absolutely Independent Blocks (AIB)** to solve the problem of slow DOM updates. Each DOM node has its own class. Tag rules are avoided in CSS. 

2010

BEM is open sourced along with some essential BEM tools. 

2015

**CSS Modules** is born with the initial commit happening in May 2015. BEM requires developers to choose unique class names and does not provide encapsulation. CSS Modules solves this by dynamically creating class names and localising styles. Thus, tooling is just as important as conventions. CSS Modules doesn't replace BEM. It makes it easier to implement BEM.