BEM stands for Block, Element, Modifier. BEM is a stricter standard for naming CSS classes for larger projects, where standards need to be enforced. BEM helps scale your project, and add meaning to your CSS. Therefore it is valuable to understand this convention.
Block
A logically and functionally independent page component, the equivalent of a component in Web Components. A block encapsulates behaviour (JavaScript), templates, styles (CSS), and other implementation technologies described below.
Blocks can be implemented in one or more technologies, for example:
- Behavior — JavaScript, CoffeeScript, TypeScript
- Appearance - CSS, Stylus, Sass, Less
- Templates — BEMHTML, BH, Jade, Handlebars, XSL
- Documentation - Markdown, Wiki, XML
Blocks being independent allows for their re-use, as well as facilitating the project development and support process.
Block Features
Blocks consists of the following features:
- Nested - Blocks can be nested inside any other blocks
- Arbitrary placement - Blocks can be moved around on a page, moved between pages or projects
- Re-use - An interface can contain multiple instances of the same block
Nested structure
Block can be nested inside any other blocks.
Element
A constituent part of a block that can't be used outside of it. For example, a menu item is not used outside of the context of a menu block, therefore it is an element.
Using elements within elements is not recommended by the BEM methodology.
Modifier
A BEM entity that defines the appearance and behaviour of a block or an element.
The use of modifiers is optional.
Modifiers are similar in essence to HTML attributes. The same block looks different due to the use of a modifier.
For instance, the appearance of the menu block (menu) may change depending on a modifier that is used on it.
Naming Convension
The naming convention follows this pattern:
.block {}
.block__element {}
.block--modifier {}
As you can notice, the element (__) differs from modifier (--), where element uses underscores and modifier use hyphens.
These self-describing styles help developers and designers to identify and understand the structure they are building.
Let's look at an example to understand this concept further.
.vehicle {}
.vehicle__door {}
.vehicle--car {}
.vehicle--car__door {}
.vehicle__door--left {}
The top-level block is vehicle
which has elements for example door
. A vehicle
also has variation, like car
. And that variation in turn has elements such as door
.
Conclusion
BEM may seem ugly, and weird. But it's a powerful naming convention for the front-end developer.