What is BEM? What are some examples?

In short, CSS BEM is a CSS naming convention for HTML classNames that allows developers to write CSS faster and maintain CSS more easily. CSS BEM uses compound names for CSS classes, those being “block__element–modifier”. BEM is very popular when working on HTML components. An HTML component is nothing but a group of HTML elements that forms a useful entity. BEM supplies a modular structure to your HTML & CSS Components. Because of its unique naming strategy, we won’t run into altercations with other CSS names.

Block, Element, Modifier, CSS methodology

Here’s an example of what a CSS developer writing in the BEM style might look like:

1
2
3
.block
.block__element
.block__element--modifier

.block
Block is a top-level abstraction of a new component; this block should be thought of as a parent.

.block__element
Element prefixed with double under__scores, are CSS selectors to identify child elements; we can use these CSS selectors to target elements with more control.

.block__element–modifier
Modifier prefixed with double — dash, are CSS selectors that identify variations of a particular element. This is used to manipulate the theme or style that a particular component without changing the look and feel of the default component itself.

In this article, we will be showing examples and topics of this BEM, CSS methodology.

Use the links below to jump to each topic or example:

  1. Valid BEM Class Naming
  2. Simple Example
  3. Advance Example
  4. Complicated Grand Children Structure
  5. Utility Classes with BEM

1. Valid BEM Class Naming

  • Names are written in lowercase Latin letters.

  • Words are separated by a hyphen -.

  • The block name defines the namespace for its elements and modifiers.

  • The element name is separated from the block name by a double underscore __.

  • The modifier name is separated from the block or element name by two double dashes –.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.block
.block__element
.block__element--modifier

.hero-text
.hero-text__sticky
.hero-text__sticky-card
.hero-text__sticky-card-button
.hero-text__sticky-flag
.hero-text__sticky-flag-picker
.hero-text__sticky-flag-links
.hero-text__sticky-flag-links-link
.hero-text__sticky-container
.hero-text__sticky-container--primary
.hero-text__sticky-container--secondary
.hero-text__sticky-container--primary-large
.hero-text__sticky-container--secondary-large
.hero-text__sticky-container-left
.hero-text__sticky-container-right

.text-with-image
.text-with-image__container
.text-with-image__container-33
.text-with-image__container-33-first
.text-with-image__container-33-second
.text-with-image__container-33-third
.text-with-image__card-primary
.text-with-image__card-secondary
.text-with-image__card-tertiary

2. Simple Example

In this simple example, we showcase an HTML card component. The top-level is set with the .card className; this is the Block.

Child items or Elements inside of .card is prefixed with .card__. You will realize that .card__description is declared.

Next, we have two buttons. They both have a similar look and feel, but the only difference is the background colors, and the width of the buttons. With these two different button variations, we can use the Modifiers conventention in BEM; here, we prefix the Modifier with .card__button, and then add double — dash, and then the modifier name; example: .card__button–submit && .card__button–cancel.

Simple Example

HTML
1
2
3
4
5
6
<div class="card">
    <div class="card__image"></div>
    <p class="card__description"></p>
    <button class="card__button--submit"></button>
    <button class="card__button--cancel"></button>
</div>
SCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.card {
  // image
  &__image {
    display: block;
  }
  // description
  &__description {
    display: block;
  }
  // button
  &__button {
    &--submit {
      display: inline-block;
    }
    &--cancel {
      display: inline-block;
    }
  }
}
CSS Output
1
2
3
4
5
6
7
8
9
10
11
12
.card__image {
  display: block;
}
.card__description {
  display: block;
}
.card__button--submit {
  display: inline-block;
}
.card__button--cancel {
  display: inline-block;
}

3. Advance Example

In this more complicated example, we showcase an HTML post-card component. The top-level is set with the .post-card className; this is the Block.

Child items or Elements inside of .post-card is prefixed with .post-card__. You will realize that there are an abundance of elements inside of the .post-card component. Here listed some examples are: .post-card__input-container, .post-card__profile, .post-card__profile-photo.

Please realize that working with BEM, all classNames are flat, meaning that there will only be allowed with once __, underscore underscore. This CSS methodology was developer by Yandex; I do have some questions myself about this.

Next, I am going to highlight the Modifiers CSS classNames in this example. You will realize that there are three buttons for this given component. We have live-video, photo-video, and live-event buttons. It is safe to say that these buttons are very similar and have a slight variation to them. It is a good call to use Modifiers for these buttons; prefixed by .post-card__btn, we now append double dash — and have the CSS classNames like .post-card__btn–live-video,.post-card__btn–photo-video, .post-card__btn–life-event.

Advance Example

HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div class="post-card">
  <div class="post-card__input-container">
    <div class="post-card__profile">
      <img class="post-card__profile-photo" />
    </div>
    <div class="post-card__search">
      <form action="" class="post-card__search-form">
        <input type="text" class="post-card__search-input" />
      </form>
    </div>
  </div>
  <div class="post-card__actions-container">
    <div class="post-card__action">
      <button class="post-card__btn--live-video"></button>
    </div>
    <div class="post-card__action">
      <button class="post-card__btn--photo-video"></button>
    </div>
    <div class="post-card__action">
      <button class="post-card__btn--live-event"></button>
    </div>
  </div>
</div>
SCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
.post-card {
    display: block;
    // input container
    &__input-container {
        display: flex;
    }
    &__profile, &__search {
        width: 50%;
    }
    // profile
    &__profile {
        display: block;
        &-photo {
        display: block;
        }
    }
    // search
    &__search {
        display: block;
        &-form {
            display: block;
        }
        &-form {
            display: block;
        }
    }
    // actions container
    &__actions-container {
        display: flex;
    }
    &__action {
        width: 33%;
    }
    // action buttons
     &__btn {
        &--live-video {
            display: block;
        }
        &--photo-video {
            display: block;
        }
        &--life-event {
            display: block;
        }
    }
}
CSS Output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
.post-card {
  display: block;
}
.post-card__input-container {
  display: flex;
}
.post-card__profile, .post-card__search {
  width: 50%;
}
.post-card__profile {
  display: block;
}
.post-card__profile-photo {
  display: block;
}
.post-card__search {
  display: block;
}
.post-card__search-form {
  display: block;
}
.post-card__search-form {
  display: block;
}
.post-card__actions-container {
  display: flex;
}
.post-card__action {
  width: 33%;
}
.post-card__btn--live-video {
  display: block;
}
.post-card__btn--photo-video {
  display: block;
}
.post-card__btn--life-event {
  display: block;
}

4. Complicated Grand Children Structure

According to BEM method, block structure should be flattened; you do not need to reflect nested DOM structure of the block. So, the class names for this case would be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div class="block">
    <div class="block__elem-1">
       <div class="block__elem-2">
          <div class="block__elem-3">
             <div class="block__elem-4">
                <button class="block__elem-5--red">
                  <span class="block__elem-6"></span>
                </button>
                <button class="block__elem-5--blue">
                  <span class="block__elem-6"></span>
                </button>
             </div>
             <div class="block__elem-7">
                <ul class="block__elem-8">
                  <li class="block__elem-9"></li>
                  <li class="block__elem-9"></li>
                 <li class="block__elem-9"></li>
                </ul>
              </div>
          </div>
       </div>
    </div>
 </div>

5. Utility Classes with BEM

Let’s not twist our arms and say the flat naming convention is a rule set to stone. I understand that the examples in this article only show components that use BEM naming conventions, but you are probably wondering, how about utility classes?

Elements that are hard to identify with a new, meaningful class name (e.g., you need a parent element with a position: relative → create <div class=”position-relative”><div class=”card”></div></div>) or uikits imported from other libraries can be used as well.

Utility classes speed up the CSS implementation and make it more manageable to customize things. Utilities like the BassCSS margin utility, example:

1
2
3
4
5
6
7
8
9
10
11
12
.m0  { margin:        0 }
.mt0 { margin-top:    0 }
.mr0 { margin-right:  0 }
.mb0 { margin-bottom: 0 }
...

.pr0 { padding-right: 0 }
.pb0 { padding-bottom: 0 }
.pl0 { padding-left: 0 }
.px0 { padding-left: 0; padding-right:  0 }
.py0 { padding-top: 0;  padding-bottom: 0 }
...

Utility classes in conjunction used with BEM looks like:

1
2
3
4
5
6
7
8
<div class="card mt12">
    <div class="card__image"></div>
    <p class="card__description pl0 pb0">
        <i class='fas fa-arrows-alt-v'>fa-arrows-alt-v</i>
    </p>
    <button class="card__button--submit pl0"></button>
    <button class="card__button--cancel pl0"></button>
</div>

Was this post helpful?

Hello, I am an enthusiastic Adobe Community Advisor and a seasoned Lead AEM Developer. I am currently serving as an AEM Technical Lead at MNPDigital.ca, bringing over a decade of extensive web engineering experience and more than eight years of practical AEM experience to the table. My goal is to give back to the AEM Full Stack Development community by sharing my wealth of knowledge with others. You can connect with me on LinkedIn.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top