DEV Community

Camilo Micheletto
Camilo Micheletto

Posted on

BEM with native nesting V2 - Even more powerful 🔥

Recently, WhatIsLove Dev wrote a fantastic article explaining how to write BEM modifiers in pure CSS, similar to Sass. In the example the technique consists in using attribute selectors and parent selectors to make the block + modifier relationship:

.tag-list__tag {
  --background-color: var(--color-red-200);

  padding-block: 2px;
  padding-inline: 6px;
  background-color: hsl(var(--background-color) / 30%);

  &[class*='--html'] {
    --background-color: var(--color-green-100);
  }

  &[class*='--github'] {
    --background-color: var(--color-gray-100);
  }

  &[class*='--ts'] {
    --background-color: var(--color-blue-200);
  }
}

Enter fullscreen mode Exit fullscreen mode

To apply a modifier, declare the base and modifier classes on the same element:

<aside class="aside box">
  <span class="aside__border aside__border--top">
    <!-- omitido -->
  </span>
</aside>

Enter fullscreen mode Exit fullscreen mode

I thought

"It would be sick if I could just write the modified class, right? After all, the prefix of the modifier class is the base class (block)."


Suffix and Prefix

The idea is simple: the suffix refers to the base class, and the prefix to its modifiers. The attribute selector supports string start and end searching, so just nest the suffix inside the prefix.

Given a class .card with modifiers .card--brand and .card--grey:

:where([class^="card"]) {
  &[class*="--grey"] {}
  &[class*="--brand"] {}
}
Enter fullscreen mode Exit fullscreen mode
  • ([class^="card"]) - Captures the element's prefix (block)
  • &[class="--grey"] - Captures the element's suffix (element/modifier)

meme do xablau

XABLAU

Downsides of the Technique

  • Attribute selectors are costly in terms of performance because they perform a substring search through the element tree.
  • In addition to class name collisions, there will be suffix collisions as well, doubling the need for careful naming.

Check out this CodePen to play around:

Top comments (0)