BEM methodology

BEM, meaning Block, Element, Modifier, is a front-end methodology gives you simple and understandable structure in your CSS code.

It is a smart way of naming your CSS classes to give them more transparency and meaning to other developers. They are far more strict and informative, which makes the BEM naming convention ideal for large project such as this.

The main idea of the naming convention is to make names of CSS selectors as informative and clear as possible to other developers on the project, describe more about what a piece of markup is doing from its name alone. By reading some HTML with some classes in, you can see how – if at all – the chunks are related; something might just be a component, something might be a child, or element, of that component, and something might be a variation or modifier of that component.

BEM splits components' classes into three groups:

  • Block: The sole root of the component.
  • Element: A component part of the Block.
  • Modifier: A variant or extension of the Block.

Naming rules

  • Names are written in lower case.
  • Words within the names of BEM entities are separated by a hyphen (-).
  • An element name is separated from a block name by a double underscore (__).
  • Boolean modifiers are delimited by double hyphens (--).
  • Key-value type modifiers are not used.

Block - the root of the component

A block name follows the block-name scheme and defines a namespace for elements and modifiers. Different prefixes can sometimes be added to block names.

.accordion {
	max-width: 37.5em;
	width: 90%;
}

Here we can see that .accordion {} is the Block; it is the sole root of a discrete entity.

Element - A component part of the Block

Elements are delimited with two underscores (__), and Modifiers are delimited by two hyphens (–).

.accordion__title {
	font-size: 0.8rem;
}

.accordion__title {} is an Element; it is a smaller part of the .accordion {} Block.

Modifier - A variant of the Block

.button {
	display: inline-block;
}
.button--blue {
	color: $blue;
}

.button--blue {} is a Modifier; it is a specific variant of the .button {} Block.

The markup might look like the following:

<a class="button button--blue" href="...">
	<span class="button__price">...</span>
	<span class="button__text">...</span>
</a>

Other developers should still have a good idea of which classes are responsible for what and how they depend on one another. Developers can then build their own components and modify the existing block to their content. Without writing much CSS, developers are potentially capable of creating many different combinations of buttons simply by changing a class in the markup. We can quickly build variations of things by using the -- modifier notation. The trick with BEM is knowing when something falls into a relevant category. Just because something happens to live inside a block it doesn’t always mean is actually a BEM element.


Base styling

Base styling, such as normalise, does not follow the standard rules. When extending the Framework however you should not extend the base styling.


Namespaces and naming convention

All names must match the consistent naming convention so that each block, element or modifier is named the same across wireframes, designs and code.

Classes that are not for components (which should follow the BEM pattern above) must use one of the following namespaces.

Atom

Use .a-* for the most basic of building blocks, such as a form label, an input or a button.

Molecule

Use .m-* for groups of atoms which are bonded together and create the smallest fundamental units, such as a form label and form input being combined to create a form row

Organism

Use .o-* are groups of molecules joined together to form a relatively complex, distinct section of an interface.

Layout

Use .l-* classes to signify that this class is used for overall page layout. For example containers, wrappers or grid.

Utilities

Use .u-* classes to signify that this class is a utility class. It has a very specific role (often providing only one declaration) and should not be bound onto or changed. It can be reused and is not tied to any specific piece of UI.

Themes

Use .t-* classes to signify that a class is responsible for adding a Theme to a view. It lets us know that UI Components’ current cosmetic appearance may be due to the presence of a theme.

Behaviour hooks

Use .js-* classes to denote behaviour (as opposed to style), but keep these classes out of your CSS.

QA hooks

Use .qa-* classes to signify that a QA or Test Engineering team is running an automated UI test which needs to find or bind onto these parts of the DOM. Like the JavaScript namespace, this basically just reserves hooks in the DOM for non-CSS purposes. Do not use ids for this prurpose.

Analytics hooks

Use .dd-* classes to signify that an Analytics or Data team is using a tool for tracking user behaviour which needs to find or bind onto these parts of the DOM. Like the JavaScript namespace, this basically just reserves hooks in the DOM for non-CSS purposes. Do not use ids for this purpose.


States

States are a sub-set of the modifiers where the modifier describes the current state of a block or element. There are two approaches to naming states in the following order of preference:

States that can be described in HTML

Where a HTML attribute defines the state of a block or element — such as ‘disabled’ — use this instead of a class name. This is an exception to the rule that all styling must be done using classes and ensures that the correct HTML attributes are always set. ARIA attributes are another good example of where this pattern should be used.

<button class="block" disabled>...</button>
<div class="block" aria-visible="true">...</div>
.block[disabled] {
	...
}

States that can not be described using HTML

Where the state is purely visual and has no HTML hook then use the prefixes is- or has- to signify that the item in question is currently styled a certain way because of a state or condition.

<div class="block is-loading">...</div>