A more JavaScript-friendly BEM naming convention

Asís García
Trabe
Published in
2 min readJan 14, 2019
Photo by Rick Mason on Unsplash

CSS Modules are a great tool for isolating component styles. And the BEM naming convention (and the underlying Block-Element-Modifier decomposition) is a great tool for understanding a component’s modular structure. At Trabe, we use both to write our React components.

The problem is, CSS Modules and the “standard” BEM naming convention don’t go well together. CSS identifiers containing dashes (-) aren't valid JavaScript identifiers. This means our preferred way of writing long class names (.using-kebab-case) and BEM modifiers (.block--modifier) can't be used in the JavaScript world:

In a previous story by David Barral, he wrote about how we tried to overcome that problem using a custom webpack loader. The story ends like this (emphasis mine):

We must always also understand the tradeoffs derived from the use of new abstractions and accept them. In this scenario, using a notation easier on the eye forced us to add a new loader, a custom classnames implementation, a custom prop-type, and to tweak the tests. Is it worth the effort? That’s something you must decide on your own.

Well… we decided that the effort was not worth it 😅. There is a much more simple solution: just stick to the lowest common denominator between CSS and JavaScript valid identifiers.

So, in recent projects we’ve started to use the following, more JavaScript-friendly BEM naming convention:

  • Blocks are written using PascalCase, like in VideoPlayer.
  • Elements are written using camelCase, joined to the block name using a single underscore (_), like in VideoPlayer_buttonsContainer.
  • Modifiers also use camelCase, but we use three underscores (___) to join the modifier to the block or element name, like in VideoPlayer___isLoading.

With this new naming convention in place, we can use the exact same names we use to write our CSS in our JavaScript code:

Is this new approach better?

With this convention you lose the old-school CSS identifiers, and thus you have to train yourself to stop writing every class using dashes. But you gain a lot in exchange:

  • You can find the JavaScript file using a CSS class with a direct search operation, without the need to reverse the CSS-to-JavaScript naming translation.
  • The CSS class for a component matches the component name.
  • You don’t need any additional code or tooling (no additional webpack loader, custom PropType, enzyme serializer, Jest module mapper, or custom classnames implementation).

So… yes, I think it’s really worth it 😄.

Update 2018/2/18: I’ve published a new story with a more in-depth look at this subject. Check it out! A comprehensive guide to using BEM with React.

--

--