BEM: blocks
BEM stands for "block, element, modifier". The methodology was created at Yandex, and today it is one of the most popular in the world. In BEM an interface is built from three kinds of entities, and everything starts with blocks.
Three entities
| Entity | What it is | Class example |
|---|---|---|
| Block | a standalone component | .card |
| Element | a part of a block, cannot live on its own | .card__title |
| Modifier | a variant of a block or an element | .card--sale |
This lesson covers only blocks. Elements and modifiers get their own lessons next.
What a block is
A block is an independent part of the interface that can be moved to another place on the page or to another site, and it will still work. A button, a search field, a menu, a product card — all of these are blocks:
<style>
.button {
padding: 8px 16px;
border: none;
border-radius: 6px;
background: seagreen;
color: white;
}
</style>
<button class="button">Buy</button>The block is styled with a single class .button. You can put this button in the header, a form or a card — it will look the same.
The block name
A block name answers the question "what is it?", not "what does it look like?". It is written in lowercase Latin letters, with words separated by a hyphen:
| Good | Bad | Why it is bad |
|---|---|---|
.search-form | .red-box | the color will change tomorrow |
.main-menu | .left-column | the menu may move to the right |
.user-card | .block1 | the name says nothing |
A block does not know where it stands
A block is responsible for how it looks, but not for its position on the page. Outer margins, position and its width in the layout are set by whoever uses the block:
<style>
.badge {
display: inline-block;
padding: 2px 8px;
border-radius: 10px;
background: gold;
font-size: 13px;
}
</style>
<p>New arrival <span class="badge">new</span></p>
<p><span class="badge">−20%</span> Discount on everything</p>.badge has no margin — so the label looks equally good both after the text and before it.
Blocks inside blocks
Blocks freely nest inside each other: a card can contain a button, a header can hold a menu and a search. Each block still stays independent and does not change its neighbour's styles:
<style>
.card { padding: 12px; border: 1px solid silver; border-radius: 8px; max-width: 220px; }
.button { padding: 6px 12px; border: none; border-radius: 6px; background: seagreen; color: white; }
</style>
<div class="card">
<p>Backpack, €40</p>
<button class="button">Buy</button>
</div>The card knows nothing about the button, and the button knows nothing about the card. They can be changed separately.
Common mistake
Giving a block outer margins "for one particular place":
<style>
.button { margin-left: 40px; padding: 6px 12px; border: none; background: seagreen; color: white; }
</style>
<button class="button">In the header it is fine</button>
<p><button class="button">But here the button has drifted</button></p>A margin needed in one place breaks all the others. The position of a block is set through its parent — the lesson on mixes shows exactly how.