Never BEM Again

During my career I have found BEM annoying.
You may ask why, as BEM is considered a good practice for handling styles and overrides.

For those who do not know what BEM is, the tldr description is BLOCK-ELEMENT-MODIFIER. For example, when using a CSS framework, your element would look like this

<button class="btn">This is a framework-designed button</button>
<button class="btn submit-btn">This would be a generic submit button modified by the design team of the product</button>
<button class="btn submit-btn large">This is our generic submit button, with modified size for a specific purpose</button>

Back to the reasons I dropped BEM.
Using classes for styling is somewhat easy and a good practice, but there is a better option with the result of less markup, more readable CSS files, making SASS/SCSS redundant and as a bonus it provides easy access for automated E2E tests.

I don’t have a name for this method, probably I would call it Context-CSS or something like this. The name implies of the technique. Though it is very similar to BEM the implementation approach is different and there are more pros.

Let’s say I have a CSS base framework. If the framework defines how buttons would look like, then why do I need to add [class=“btn”] for every button I place? Some say it’s good for using DIVs as buttons, but this reduces accessibility of the page, disables keyboard navigation and I can’t find a good reason for doing that.

So my framework would style buttons by defining

button {
   /* whatever */
}

Now back to the context thing. Almost every app screen I have been working on had some context defining the current state of the UI.
I could reach (almost) any element with a maximum of 3 nested selectors.
For example

<section aria-role="settings-view">
<!-- more elements -->
  <div aria-role="settings-form">
    <!-- more elements -->
    <button aria-role="submit">Submit</button>
  </div>
</section>

Now if my styling requires overrides for the submit button specifically for the settings form inside the settings screen, then my CSS (no sass) would be both readable and simple

[aria-role="settings-view"] [aria-role="settings-form"] [aria-role="submit"] {
  /* override here */
}

I could change all buttons in the settings view to other color with a shorter rule

[aria-role="settings-view"] button {
  color: lime;
}

All the rest are based by the framework, that relates to buttons and not classes for buttons.

Less CSS payload for the client, less files to deal with (and more readable), most of the times less markup, accessibility, easy and meaningful tags for writing automations.

Another bonus is performance. Attribute style rules are stronger than class rules. Since there aren’t much overrides, there are close to zero classes spread in the HTML (less computations). The overrides are very specific to the targeted elements, therefore the computation weight focuses only on the overrides.

I could break the DOM anytime while as long as I keep the nesting (which has a reason for being nested).

In my own experience, this approach was easier to maintain, to understand and to be applied by all levels of developers. It is very friendly with the automation team.

If you have any kind of an approach that is different non-mainstream, I would like to hear how you do it. Comments would be appreciated.

Happy coding.

 
55
Kudos
 
55
Kudos

Now read this

Micro frontends, in practice

“Microfrontends” is a hot topic nowadays. Since front-end projects become big and feature-rich, as the codebase gets bigger, tooling and organization are essential for a successful project. I would rather think of micro-frontends in... Continue →