My notes on BEM

dwayne profile image Dwayne Crooks ・3 min read

Block, Element, Modifier or BEM is an approach to front-end web development that helps you to create reusable UI elements.


BEM has three main benefits that makes it attractive to use.

  1. It is easy to use. We simply need to adopt a naming convention.
  2. It promotes modularity. The independent blocks and CSS selectors that it encourages you to write makes your code reusable and loosely coupled.
  3. It gives your CSS a solid structure that remains straightforward to manage throughout the lifetime of your project.

An extra benefit that I really like is that it's wonderful to use with Elm.

What's a block?

A block is a standalone entity that is meaningful on its own.

For e.g. a button, slider, menu, modal or window.

What's an element?

An element is a part of a block that has no standalone meaning and is tied to its block.

For e.g. a menu item or a window's header.

What's a modifier?

A modifier is a flag or key-value attribute on a block or element that is used to change appearance or behavior.



<block>        ::= <name>

<name>         ::= <letter> <alphanumeric>* ('-' <alphanumeric>+)?
<alphanumeric> ::= <letter> | <digit>
<letter>       ::= 'a' | ... | 'z' | 'A' | ... 'Z'
<digit>        ::= '0' | ... | '9'

A <name> starts with a letter and is followed by zero or more alphanumeric characters. It's optionally followed by a hyphen and one or more alphanumeric characters.

A <block> is any <name>.

For e.g. button, r2, r2-d2, c-3po.


Any DOM node can be a block if it accepts a class name.

For e.g.

<button class="button">...</button>


  • Use a class name selector only.
    • Good: .button {...}
  • No tag name or ids.
    • Bad: button.button {...}, #id.button{...}
  • No dependency on other blocks or elements on the page.
    • Bad: .window .button {...}, .menu__item .button {...}



<element>      ::= <block> '__' <element-name>
<element-name> ::= <name>

An <element> is a <block> followed by double underscore followed by an

An <element-name> is any <name>.

For e.g. menu__item, c-3po__head


Any DOM node (that accepts a class name) within a block can be an element.

For e.g.

<ul class="menu">
  <li class="menu__item">...</li>


  • Use a class name selector only.
    • Good: .menu__item {...}
  • No tag name or ids.
    • Bad: li.menu__item {...}, #id.menu__item{...}
  • No dependency on other blocks or elements on the page.
    • Bad: .menu .menu__item {...}, .window__header .menu__item {...}



<modifier>        ::= <block-modifier>
                    | <element-modifier>

<block-modifier   ::= <block> '--' <modifier-name>
<element-modifier ::= <element> '--' <modifier-name>

<modifier-name>   ::= <modifier-flag>
                    | <modifier-key> '--' <modifier-value>

<modifier-flag>  ::= <name>
<modifier-key>   ::= <name>
<modifier-value> ::= <name>

A block or an element can be modified. A <modifier-name> can be used to
represent a boolean or key-value attribute.

For e.g.

  • Boolean modifiers: button--disabled, menu__item--active
  • Key-value modifiers: button--size--large, window__header--theme--xmas


A modifier is an extra class name which you add to a block or element DOM node. Add modifier classes only to the block or element they modify and keep the original class.

A good example:

<ul class="menu">
  <li class="menu__item menu__item--active">...</li>

A bad example:

<ul class="menu">
  <!-- The original element class `menu__item` isn't kept. -->
  <li class="menu__item--active">...</li>


  • Use modifier class name as selector.
    • Good: .button--disabled {...}
  • You're allowed to alter elements based on a block-level modifier.
    • Good: .menu--open .menu__item {...}


Posted on Mar 31 by:

dwayne profile

Dwayne Crooks


A full stack web developer who has an interest in programming language theory, interpreters, compilers and type theory. I enjoy programming with Elm and Haskell in my free time.


markdown guide