BEM'a should not exist


BEM should not exist. There are a huge number of reasons not to use this methodology, but because of its ease of use and lack of understanding of the work of CSS and HTML, the methodology has spread widely among front-end users around the world, in most cases among the developers of the CIS. BEM is now used both in large Russian-language projects (Yandex, Habr), and in some frameworks ( react-md ). This article will go into a detailed analysis of the pros and cons of this approach to development. All examples of layouts will be taken from the official BEM website .

Abbreviation BEM - block / element / modifier. Any layout or design can be visually divided into blocks, for example - the sidebar of the site. Each block can contain one or more elements. Elements can have state modifiers (active, disabled), additional classes for changing borders, widths, background colors, etc.

The idea of ​​breaking the layout into blocks is not new, what BEM suggests is to extend the class names, always make the elements dependent on the block name and set any class globally. It helps literally anywhere and leads to dire consequences in the design of projects. The following are described by item problems in using BEM'a:

Unreadable html

This is the layout from the official BEM website . Extended and php-like CSS class names make any layout completely unreadable, interspersed with attributes:

<ul class="article-rewind article-rewind_type_static article-rewind_lang_ru">
    <li class="article-rewind__next">
        <div class="article-rewind__next-text">Читать далее</div>
        <a class="article-rewind__next-link" href="">Основные понятия</a>

The following is a sample of the layout without inheritance in the class name of the block name, the modifiers are bound to the main class via inheritance in SCSS, and not the text name of the class:

<ul class="article-rewind type-static lang-ru">
    <li class="next">
        <div class="text">Читать далее</div>
        <a class="link" href="">Основные понятия</a>

.article-rewind {
  margin:      0;
  padding:     0;
  list-style:  none;
  &.type-static {
    position:  relative;
    display:   flex;
  &.lang-en {}
  &.lang-ru {}
  &.lang-uk {}
  & > .next {
    position:      relative;
    flex-grow:     1;
    align-self:    center;
    margin-right:  88px;
    text-align:    right;
    .text {
      font-size:   16px;
      position:    absolute;
      right:       0;
      margin-top: -32px;
    .link {
      font-size:   40px;
      line-height: 46px;

Difficulties with modifier inheritance

Any class in BEM is global, and modifiers are no exception. Where CSS allows the main class, for example, button to inherit several classes active, disabled, error , you will set all this globally, inheriting the names of the parent blocks and elements in the name. Such an approach is to ignore the possibilities of CSS as nesting elements into a class and lengthening names out of the blue:

    <h1 class="article__heading_level_1 article__heading_level_1_active"></h1>

An example of modifier inheritance through SCSS, and not through words in the class name:

    <h1 class="heading active"></h1>

.article {
  h1.heading {
    font-size:   50px;
    line-height: 64px;
    float:       left;
    &.active {
      color:     #ccc;

All classes are pseudo-global.

In fact, there is nothing wrong with global classes. The problem is that the name of the block or element is saved in the class name and it is no longer possible to use it outside the block and the globality becomes useless. In addition, global classes hang in the browser, for example, promo-section_color_which does everything that it does - it changes the background color to white, and this can only be applied to the .promo-section block . For other blocks with a white background, make a new class with a hardcode in the name. Elements cannot be used everywhere in a project, although it is technically possible to apply classes everywhere:

  <div class="promo-section promo-section_color_white"></div>

Instead of binding to the block via text in html, you can make the classes truly global, reuse in other sections and absolutely not lose anything:

  <div class="promo-section background-white"></div>

.promo-section {
  position: relative;
  padding:  0 0 70px;
.background-white {
  background-color: white;

Prohibition of using semantics

A verbatim quote from the documentation:
BEM CSS also does not recommend using tag selectors or id selectors.
In places where you can use mixin'a or cycle in the preprocessor to use the inheritance via html-tag, you can not do this:

  <h1 class="article__heading article__heading_level_1"></h1>
  <h2 class="article__heading article__heading_level_2"></h2>
  <h3 class="article__heading article__heading_level_2"></h3>

Here styles could be set via h1, h2 and so on, but now instead of a link to tags, we globally have the specified class “article__heading_level_1”.

  <h1 class="heading"></h1>
  <h2 class="heading"></h2>
  <h3 class="heading"></h3>

@for $index from 1 through 6 {
  h#{$index}.heading {
    font-size: (42px / $index);
/* mixin output */
h1.heading {font-size: 42px;}
h2.heading {font-size: 21px;}
h3.heading {font-size: 14px;}
h4.heading {font-size: 10.5px;}
h5.heading {font-size: 8.4px;}
h6.heading {font-size: 7px;}

Implies the layout only blocks

In each large template there are small elements like buttons, dropdowns, titles, subtitles, sections, etc. But in BEM you don’t have them, as any element without a block is also prohibited.
An element is always part of a block and should not be used separately from it.
Do you want a dropdown not only in the header? On the BEM site, the dropdown in the header is effected as a popup at the root of the body. In fact, this item is a prohibition of creating a full-fledged template, and not something more complicated than landing.


They are not. BEM destroys the concept of the template, prohibits the use of CSS functions, pushes the developer to the hardcode. I would be happy to praise the methodology in the comments, there will be food for thought.

Original article:

Also popular now: