BEMIT: The Next Step in the Development of BEM by Harry Roberts

Original author: Harry Roberts
  • Transfer
Everyone who has been following me or my work for some time no doubt knows that I am a huge fan of the BEM naming convention. What I will discuss in this article is not an alternative or other agreement on the names of BEM, but an addition to it: small additives that will raise BEM a notch. This extended BEM syntax has been dubbed BEMIT because it includes some paradigms and patterns from the (yet unpublished) inverted triangle CSS architecture (ITCSS). BEM + ITCSS = BEMIT.

Recall what BEM is - it works by breaking all the classes in the code base into three groups:

• Block: The only root element of the component.
• Element: Component of the Block.
• Modifier: Option or extension of the Block.

Blocks, Elements, and Modifiers: BEM. Absolutely any class in the project falls into one of these categories, and that is why BEM is so good - it is incredibly simple and straightforward.

The meaning of BEM is to make your markup more transparent and understandable. BEM tells developers how classes relate to each other, which is important in complex or multi-level DOMs. For example, if I asked you to remove all user-related classes in the following HTML snippet that you would get rid of?

...



Definitely, we would start with user, but anything below it would be more of a hunch, albeit justifiable. However, if we rewrite this fragment with BEM:

...



Here we see for sure that user, user - premium, user__photo and user__bio are interconnected. We also see that media, media__img and media__body are also interconnected, and avatar is a lone Block that does not have Elements and Modifiers.

This level of detail in our classes is excellent. It allows us to make safer and more informed decisions about what should be done and how you can use, reuse, modify or delete items.

The only drawback of BEM is that it only tells which classes to use in relative terms, as well as how the classes are related. He does not make it clear how such elements behave, work, or should be realized in a global, non-relative sense.

From this point of view, I decided to expand BEM and make BEMIT. BEMIT does not add new types of classes - we still only have Blocks, Elements or Modifiers, but at the same time it adds information about usage and status.

Namespaces



The most common types of namespaces are c- for Components, o- for Objects, u- for Utilities and is- / has- for states (this is described in more detail in the article that I refer to). With this in mind, the above HTML should be rewritten as follows:

...



Based on this, I see that we have a reusable abstraction in a media object (o-media *) and two implementation components (c-user * and c-avatar). These classes still remain Blocks, Elements, or Modifiers: a new classification has not been added to them, but a new level of value has been added.

These namespaces are associated with levels contained in the CSS architecture in the form of an inverted triangle, which means that each class has a specific place in our project (and in our file system).

Responsive Suffixes


The next thing BEMIT adds to traditional BEM naming is responsive suffixes. These suffixes take the format @ <breakpoint>, and tell us this class in the following size:

...



Here we have o-media @ md, which means that the media object will be at this breakpoint. Other possible examples:

• u-hidden @ print - a utility class that hides elements when printing.
• u-1/4 @ lg - a utility that displays objects a quarter of the width at a large control point
• o-layout @ md - a layout object at the middle control point.

The @ sign is a human-readable and logical way to indicate conditional states. It allows developers to learn about any potential permutations or appearance of this part of the UI in question at a glance.

Note: You should not use the @ symbol in the CSS file as follows:

@media print {
  .u-hidden\@print {
    display: none;
  }
}


Health Check


Having such strict and clear patterns in our HTML, we can do many things. Firstly, and most obviously, we can write much more expressive and rich code for our colleagues, which means that they will be able to understand and understand the state and form of the project much faster. They will also be able to contribute in a more consistent way.

But another fun side effect is that we can run a visual health check for our UI. Using subscript selectors, we can designate, and therefore visualize the overall appearance of the page, based on the types of classes it contains:

/**
 * Outline для всех классов.
 */
[class] {
  outline: 5px solid lightgrey;
}
/**
 * Outline всех BEM-элементов.
 */
[class*="__"] {
  outline: 5px solid grey;
}
/**
 * Outline всех BEM Модификаторов.
 */
[class*="--"] {
  outline: 5px solid darkgrey;
}
/**
 * Outline для всех классов объектов.
 */
[class^="o-"],
[class*=" o-"] {
  outline: 5px solid orange;
}
/**
 * Outline для всех классов компонентов.
 */
[class^="c-"],
[class*=" c-"] {
  outline: 5px solid cyan;
}
/**
 * Outline для всех "классов отзывчивости".
 */
[class*="@"] {
  outline: 5px solid rosybrown;
}
/**
 * Outline для все "Hack classes".
 */
[class^="_"] {
  outline: 5px solid red;
}


Of course, this is not a panacea - some fragments can be both Components and Elements at the same time - but if we write classes in a selective order (i.e. in order from less important to more important, and thus, the hardest is at the end), we can Get a good visual snapshot of the appearance of any particular page.

We can run a health check in various ways, but the simplest is to embed the entire volume in the Scope class:

.s-healthcheck {
  ...
  /**
   * Outline all Responsive classes.
   */
  [class*="@"] {
    outline: 5px solid rosybrown;
  }
  ...
}


... which can then be added to the html element when you need to enable validation:



Finally


We have some simple additions to BEM that turn it into BEMIT: adding information to the beginning and end of the standard Block, Element, or Modifier class to provide us with more data on how classes behave in a non-relative sense. Some more examples:

.c-page-head {}
@media screen and (min-width: 15em) {
  .u-text-center\@sm {}
}
.o-layout__item {}
@media print {
  .u-color-black\@print {}
}



Also popular now: