CSS BEM Naming Convention

Official Documentation and Further Reading

In the world of web development, writing CSS that is maintainable, reusable, and easy to understand becomes increasingly challenging as projects grow in size and complexity.
Without a proper naming strategy, CSS codebases can quickly become unwieldy, leading to specificity issues and making future modifications difficult.
This is where the BEM naming convention comes to the rescue.

What is BEM?

BEM stands for Block, Element, Modifier - a methodology developed by Yandex, a Russian search engine company. It’s a naming convention that helps you achieve reusable components and code sharing in front-end development.

The core principle behind BEM is to break down user interfaces into independent blocks, create a clear relationship between HTML and CSS, and maintain low specificity in your selectors. This approach ensures everyone working on a project uses the same language and structure when writing CSS.

The Three Parts of BEM

1. Block

A Block represents a standalone component that is meaningful on its own. Think of blocks as the larger, independent sections of your interface.

Examples of blocks include:

  • Header
  • Navigation menu
  • Search form
  • Card
  • Button

In BEM, blocks are simply represented by class names:

1
2
3
.button { }
.header { }
.menu { }

2. Element

Elements are parts of a block that have no standalone meaning and are semantically tied to their block. Elements are denoted by adding double underscores (__) after the block name.

Examples of elements within blocks:

  • Menu items (part of a menu block)
  • Header logo (part of a header block)
  • Form input (part of a form block)
1
2
3
.menu__item { }
.header__logo { }
.form__input { }

3. Modifier

Modifiers are variations or different states of blocks or elements. They are used to change appearance, behavior, or state. Modifiers are denoted by adding double hyphens (--) after the block or element name.

Examples of modifiers:

  • Disabled button
  • Active menu item
  • Large input
1
2
3
.button--disabled { }
.menu__item--active { }
.form__input--large { }

A Practical Example

Let’s create a simple card component using BEM conventions:

1
2
3
4
5
6
7
8
9
<div class="card">
<img class="card__image" src="image.jpg" alt="Card image">
<div class="card__content">
<h2 class="card__title">Card Title</h2>
<p class="card__text">Card description text goes here.</p>
<button class="card__button card__button--primary">Primary Action</button>
<button class="card__button card__button--secondary">Secondary Action</button>
</div>
</div>
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
/* Block */
.card {
border: 1px solid #ddd;
border-radius: 4px;
overflow: hidden;
max-width: 300px;
}

/* Elements */
.card__image {
width: 100%;
height: auto;
}

.card__content {
padding: 16px;
}

.card__title {
margin-top: 0;
font-size: 18px;
}

.card__text {
color: #666;
}

.card__button {
padding: 8px 12px;
border: none;
border-radius: 4px;
cursor: pointer;
margin-right: 8px;
}

/* Modifiers */
.card__button--primary {
background-color: #0066cc;
color: white;
}

.card__button--secondary {
background-color: #f5f5f5;
color: #333;
}

Benefits of Using BEM

  1. Modularity - BEM promotes creating reusable components that can be easily moved around your codebase without breaking things.

  2. Readability - By looking at a class name, you can immediately understand its purpose and how it relates to other elements on the page.

  3. Low Specificity - BEM makes CSS specificity very flat and low because everything is a class and nothing is nested. This prevents specificity conflicts and makes your CSS more maintainable.

  4. Team Collaboration - BEM gives everyone on a project a declarative syntax to share so they’re on the same page. This common language helps teams work more effectively together.

  5. Developer Confidence - With strict BEM conventions, you can update and add to your CSS with confidence that your changes will not have unexpected side effects.

Common BEM Mistakes to Avoid

1. Creating Elements of Elements

Avoid nesting elements within elements in your class naming. This is a common mistake:

1
2
3
4
5
6
<!-- Incorrect -->
<div class="card">
<div class="card__content">
<h2 class="card__content__title">Title</h2>
</div>
</div>

Instead, keep the structure flat:

1
2
3
4
5
6
<!-- Correct -->
<div class="card">
<div class="card__content">
<h2 class="card__title">Title</h2>
</div>
</div>

2. Forgetting to Name Child Elements

Don’t omit class names from child elements in your HTML. Leaving those classes off may be more succinct, but it will increase risks of cascade issues in the future.

3. Using Single Underscores or Hyphens

BEM names intentionally use double underscores and double hyphens instead of single ones to separate Block-Element-Modifier. This allows single hyphens to be used as word separators within names.

1
2
3
4
5
/* Correct */
.block-name__element-name--modifier-name { }

/* Incorrect */
.block-name_element-name-modifier-name { }

Best Practices

  1. Use meaningful names - Your class names should be descriptive and clearly indicate the purpose of the element.

  2. Keep blocks independent - Blocks should not depend on other elements on a page to function correctly.

  3. Avoid excessive nesting - BEM is designed to keep specificity low, so avoid deeply nested selectors.

  4. Use modifiers wisely - Only create modifiers when you have genuine variations of a block or element.

  5. Be consistent - Stick to the BEM naming convention throughout your project for maximum benefit.


CSS BEM Naming Convention
https://www.hardyhu.cn/2024/11/23/CSS-BEM-Naming-Convention/
Author
John Doe
Posted on
November 23, 2024
Licensed under