Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

BEM: elements

A block rarely consists of a single tag: a card has an image, a heading and a price. In BEM such parts are called elements. An element makes sense only inside its block — a card heading without a card means nothing.

The element name

An element name consists of the block name, two underscores __ and the name of the part:

<style>
  .card { padding: 12px; border: 1px solid silver; border-radius: 8px; max-width: 220px; }
  .card__title { margin: 0 0 4px; font-size: 18px; }
  .card__price { color: seagreen; font-weight: bold; }
</style>
 
<div class="card">
  <h3 class="card__title">Backpack</h3>
  <span class="card__price">€40</span>
</div>

One glance at .card__price tells you: this is a price, and it lives in a card. If the name has several words, they are joined with a hyphen: .card__old-price.

An element belongs to the block

An element can sit at any depth in the markup — directly in the block or inside wrappers. All that matters is that it is inside its block:

<style>
  .profile { display: flex; gap: 10px; align-items: center; }
  .profile__avatar { width: 40px; height: 40px; border-radius: 50%; background: plum; }
  .profile__name { font-weight: bold; }
  .profile__role { color: gray; font-size: 14px; }
</style>
 
<div class="profile">
  <div class="profile__avatar"></div>
  <div>
    <div class="profile__name">Anna</div>
    <div class="profile__role">designer</div>
  </div>
</div>

The name and the role sit in a nested <div>, but they are still elements of the profile block. A wrapper without its own styles needs no class.

Why names do not repeat the nesting

A name never has two elements in a row: not .menu__list__item__link, but simply .menu__link. The name describes which block the element belongs to, not the path through the tag tree:

RightWrong
.menu__item.menu__list__item
.menu__link.menu__list__item__link

Flat names are shorter, and most importantly, the markup inside the block can be rebuilt: add a wrapper or remove one, and not a single class has to be renamed.

Element or a new block

If a part can be used apart from its parent, it is not an element but a standalone block. The "Buy" button in a card is a separate button block: it also appears in the cart and in forms. But the card price is not needed outside the card — it is the card__price element. If an element grows a complex structure of its own, it is also worth turning into a new block.

Common mistake

Using an element outside its block "because the styles fit":

<style>
  .card__title { margin: 0 0 4px; font-size: 18px; color: rebeccapurple; }
</style>
 
<section>
  <h2 class="card__title">Customer reviews</h2>
</section>

The heading looks fine now, but as soon as the card changes, the reviews section changes with it. If the styles are needed elsewhere, make a shared block, for example .heading.

Thanks for reading!

Donate to the site — we work hard for you.