How To Avoid Long BEM Modifiers

2 minCSS
BEM Modifiers Image

Before we begin, we should all get on the same page.

What is BEM?

First of all, BEM is a naming convention. In my opinion, it makes the CSS easier to read and understand. It makes it easier to scale and generally easier to work with. BEM is an abbreviation of the overall concept. The elements of the structure are Block, Element, and Modifier. The descriptions of the examples are inspired by the official guide.

Block

This is a standalone entity that has its own meaning and purpose. The block is .button.

.button {
    display: inline-block;
    padding: 1em;
}
scss

Element

This should be a part of a block that has no standalone meaning and purpose. It should be semantically tied to its block. The element is &__text.

.button {
    display: inline-block;
    padding: 1em;

    &__text {
        font-size: 1em;
        font-weight: 400;
    }
}
scss

Modifier

This should be a flag on a block or an element. Here we are able to change appearance or behavior. The modifier is &--bold.

.button {
    display: inline-block;
    padding: 1em;

    &__text {
        font-size: 1em;
        font-weight: 400;

        &--bold {
            font-weight: 700;
        }
    }
}
scss

One of the most important rules is that you can’t have an element inside an element, and you can’t have a modifier inside a modifier.

What is the problem?

With BEM modifiers, the naming convention can result in very long selectors. This can damage readability.

We could make modifiers like this:

.button {
  &.--small {
    height: 2em;
  }
}
scss

In this way, we could do this <button class="button --small"></button>.

Instead of this:

.button {
  &--small {
    height: 2em;
  }
}
scss

Which results in longer selectors <button class="c-button c-button--small"></button>.

It would make it easier to get an overview when reading the outputted code. We just need to avoid making classes named --modifier outside of a block. That would also be weird.

Thank you for your time!