BEM naming convention in CSS

BEM naming convention in CSS

Confused about how to name your classes in CSS? Use the BEM class naming convention!

Why use a class naming convention for CSS?

It is possible to name classes in CSS without a well-defined convention. However, as projects start to grow larger, the lack of a class naming convention can negatively impact scalability.

Haphazard naming (plus use of ids/tags) and subsequent styling can created layers of nested CSS of differing specificity such that any new classes produce unpredictable results.

This is where BEM comes in! Naming conventions for CSS like BEM aim to eliminate these drawbacks while at the same time promoting good coding architecture and practices.

What is BEM?

BEM stands for Block-Element-Modifier. According to this convention, every HTML element will be treated either as a Block, an Element, or a Modifier (and it's class will be named accordingly).

Let's talk about each of these in isolation.

  • Block: In BEM, a block is a standalone component that does not depend on any other entity on the page to derive it's meaning. Blocks are independent, reusable components. Eg: A card component which displays certain details (we will come back to this example later).
  • Element: An element is the sub-unit of a block. Elements are entities inside blocks, which would not have any meaning by themselves without their parent block. Eg: A picture inside the card block defined above.
  • Modifier: A modifier is a class which adds some additional features to an existing block/element. For eg: If we have a button block, we can have a modifier to make that button a white-coloured button.

BEM Syntax

Having spoken about the different types of classes in BEM. Let's take a look at the syntax.

image.png

It is pretty straightforward.

  • Classes for blocks are denoted as-is. Consider that you have a card block. You can go ahead and simply give it a card class.
  • Classes for elements inside blocks are denoted with a double-underscore. So a picture element inside the card block can have a class name card__picture.
  • Classes for modifiers are denoted with a double-dash.
    A modifier which turns the card (block) white can be denoted with the class card--white and a modifier which turns the (element) picture inside the card white can be denoted with the class card__element--white.

BEM example

Confused? Let's pick up an example.

We will apply the BEM convention to create a simple card component:

image.png

image.png

  • Block: The card is the Block in this example hence we give it's div the card class. We treat the card as an independent, reusable entity.
    Why and how do we make this distinction?
    Ask yourself if the card is indeed an independent entity. Can you reuse it elsewhere across the project (and perhaps even other projects) as an independent component? If the answer is yes, go ahead and treat it as a block.
  • Element: The unordered list of card-details is the element. It is tied to the card component. Will the card-details be (re)usable anywhere except inside a card? No! Thus we treat card-details as an element with the class card__details.
  • Modifier: We use a modifier card--orange to give the card an orange background color. Why not give a background-color of orange to the card class itself? Remember that components are reusable units. What happens if we want to add 3 more cards with colours red, green and yellow? We add modifiers for each colour (eg: card--red) and keep the block card class reusable!

Why use BEM?

Some of the reasons I prefer to use the BEM naming convention:

  • Component-driven architechture: The BEM convention forces you to think of your HTML and CSS documents in terms of components and their sub-units. It makes component-driven thinking the default instead of an after-thought.
  • Reusability: As a side-effect of component-driven thinking, all the blocks you create will be reusable across the project.
  • Prevents unintended side-effects: One of the key tenets of BEM is that classes should have a low-specificity. This, along with avoiding the use of ids and tags makes adding new classes easier and prevents unintened consequences. For eg. You apply a new class but the element does not change it's style because it has several classes/ids/tags of differing specificity.
    Such scenarios can be avoided by adhering to BEM.

Additional Points

  • Avoid nested class names. In our card example, if we have a title for the card inside card__picture, BEM prefers to avoid nesting class names and we can give the title a class named simply card__title, instead of something like card__picture __title.
  • Longer words can be broken up with a dash. For eg. we can add a modifier to the btn class as btn--state-success.
  • Rules are not binding and they can be broken/bent if you have a good enough reason. Remember, BEM is a convention designed to make your life simpler!

Summary

Critics often point out how the BEM convention gives the code a slightly clunky feel. If you are not a fan, there are several other class naming conventions which you can look up on the internet for comparsion. In my opinion, the pros certainly outweigh the cons and once you start using it (or not), you will surely notice the difference!