My notes on BEM
Tags: bem, css
Published: 2020-03-31 12:26:31

---
title: My notes on BEM
published: true
description: 
tags: bem, css
---

**B**lock, **E**lement, **M**odifier or **BEM** is an approach to front-end web development that helps you to create reusable UI elements.

## Benefits

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](https://elm-lang.org/).

## 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

**Naming**

```
<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`.

**HTML**

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

For e.g.

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

**CSS**

- 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

**Naming**

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

An `<element>` is a `<block>` followed by double underscore followed by an
`<element-name>`.

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

For e.g. `menu__item`, `c-3po__head`

**HTML**

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

For e.g.

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

**CSS**

- 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

**Naming**

```
<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`

**HTML**

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:

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

A bad example:

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

**CSS**

- 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 {...}`

## Resources

- [BEM](http://getbem.com/)
- [Naming Conventions](https://cssguidelin.es/#naming-conventions)