UX Design and Development course

BEM The BEM CSS Method

One of the most common examples of a methodology in programming is Object-Oriented Programming. It's a programming paradigm embodied by many languages. In some ways, BEM is similar to OOP. It's a way of describing reality in code, a range of patterns, and a way of thinking about program entities regardless of programming languages being used.

The BEM method has two parts. One is the structure and naming convention and the other is the means of application. The BEM system actually goes as far as using a JSON structure with a JS based templating engine called BEMHTML. FOr the purposes of this course, we are going to focus on the organization strategies of the system.

Block

A block is an independent entity, a "building block" of an application. A block can be either simple or compound (containing other blocks).

An example would be a search block as it is made up of two or more elements.

Block Independence

As projects grow, blocks tend to be added, removed, or moved around the page. For example, you may want to swap the Logo and Auth block or to place the Menu under the Search block. To make this process easier, blocks must be independent.

An independent block is implemented in a way that allows arbitrary placement — anywhere on the page, including nesting inside another block.

Independent CSS

From the CSS point of view it means that:

  1. A block (or an element) must have a unique "name" (a CSS class) that could be used in a CSS rule.
  2. HTML elements must not be used in CSS selectors .menu td as such selectors are inherently not context-free.
  3. Cascading selectors should be avoided.

Naming for independent CSS classes

CSS class for a block coincides with its block name, in this example, menu is the block name and the class.

<ul class="menu"></ul>

CSS class for an element is a block name and an element name separated by some character(s). In this example, the block name of menu is extended to use the element name of item. It is the use of the double underscore __ to denote this relationship.

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

BEM states that is is necessary to include block name into a CSS class for an element to minimize cascading.

__What does that mean?__ By using this naming convention, you are in essence writing selectors that are easy to follow and still convey a lot of meaning.

BEM Naming convention

We use hyphen to separate words in long names (for example, block-name) and two underscores to separate the name of the block form the name of the element block-name__element-name.

But you can use any other separators for it.

E.g.:

  • block-name--element-name or
  • blockName-elementName

Element

An element is a part of a block that performs a certain function. Elements are context-dependent: they only make sense in the context of the block they belong to.

Again, using the search block for an example, the search block is made up of a text element and a button element. These two elements are able to stand alone or be used in other blocks.

Modifier

To avoid developing another block that is only minimally different from an existing one, we can use a modifier.

A modifier is a property of a block or an element that alters its look or behavior.

A modifier has a name and a value. Several modifiers can be used at once.

Modifiers come in many forms, they could change the color of a block, they could be used to denote activity or state of a module like setting a tab as .current.

Modifiers closely adhere to the OOCSS method of UI modifications. Example of HTML that uses this method to modify an existing module is:

<ul class="menu menu_size_big menu_type_buttons"></ul>

It's corresponding CSS would be something like:

.menu {
  // CSS code for the primary block
}
.menu_size_big {
  // CSS code to specify a height different from that of it's parent block
}
.menu_type_buttons {
  // CSS code to change item's look like buttons
}

Notice how each modifier used the name of the parent block as a convention to alert the reader that this is to used as a modifying class on the .menu selector.

Element modifiers

Element modifiers are implemented in the same fashion that block modifiers are. They simply extend the convention of block__element with state.

.menu__item_state_current { … }

This is not to replace the primary element class of block__element, it is to be extended in the DOM like so:

<ul class="menu">
  <li class="menu__item">Index</li>
  <li class="menu__item menu__item_state_current">Products</li>
  <li class="menu__item">Contact</li>
</ul>

Layout

One of the parts not clearly specified in the BEM method is layout. According to the BEM definitions, layout is simply a larger Block that is made up of smaller blocks.

For example, the header block on BEM could consist of logo, navigation, search and log in blocks.

BEM Example structure

Each tag below represents something in the design. Be it the page, head, menu, etc. Preceding each tag name is either a b: for block or an e: for element.

  <b:page>
    <b:head>
      <b:menu></b:menu>
      <e:column>
        <b:logo/>
      </e:column>
      <e:column>
        <b:search>
          <e:input/>
          <e:button>Search</e:button>
        </b:search>
      </e:column>
      <e:column>
        <b:auth></b:auth>
      <e:column>
    </b:head>
  </b:page>