Why Mythic uses BEM

One of the concerns brought up about Mythic is that it uses the BEM (Block-Element-Modifier) class-naming system. This was a system that I struggled to understand the need for when I was first introduced to it. It’s an easy system to understand. But, the “why use it” part is often hard to grasp for some.

In this post, I’m going to introduce BEM, explain in greater detail why we’re using it in Mythic, and why it fits well within the WordPress parent-child theme paradigm.

What is BEM?

BEM stands for Block-Element-Modifier. It’s a CSS class-naming system for your markup. There are several flavors of BEM where some folks add their own twists to it, but they’re all built with the same foundation.

BEM is a block-based system.

What I mean by this is that it helps you think of each piece of your theme as an individual component. Some are reused. Some are not. Rather than looking at the overall design of the theme, BEM looks at things on a block/component level.

I personally prefer thinking of blocks as “components.” The term feels more comfortable to me, but I’ll stick with the “block” terminology in this post to not throw you too far off track.

Some example markup

Let’s look a typical block of stuff. The post <article> element is something that gets reused a lot. Here’s the plain HTML view of a simplified post:

<article>
    <header>
        <h1>Post Title</h1>
        <div>Written by Justin Tadlock</div>
    </header>
    <div>
        Some post content.
    </div>
</article>

The post is one block on its own. It also has several “elements,” such as the title, byline, and content. Let’s add some classes using the BEM system.

<article class="entry entry--type-post">

    <header class="entry__header">

        <h1 class="entry__title">Post Title</h1>

        <div class="entry__byline">Written by Justin Tadlock</div>

    </header>

    <div class="entry__content">
        Some post content.
    </div>

</article>

For anyone who’s done any decent amount of coding, you can see that all the classes are tied to the initial entry block class.

If you’re new to BEM, those double underscores (__) and double hyphens (--) mixed in probably look really ugly. The first time I saw them, I asked, “Why not just use a single hyphen?”

In smaller projects, I’d argue that just some well-named classes would go a long way toward doing pretty much anything you want. However, theme development today is not quite as simple as it once was where you can get by with a tiny stylesheet and no standard naming scheme.

This is even more true for themes released to the public, such as on WordPress.org or ThemeForest. When designing a theme for public release, you have to cover every component that’s possible with WordPress’ front end output. With larger client sites, you often have many of the same concerns.

And, let’s face it, WordPress’ default classes on many of its HTML elements are just all over the place. There’s no standard. Much of this is simply things getting tacked on for over a decade with no style guide for front-end components. Mythic attempts to standardize as many of the front-end classes as possible.

What do the underscores and hyphens mean?

Each block gets the main class name. In the post example, that name is entry. Everything else within the block builds off that name.

When you see a double underscore, such as entry__title, it tells us that title is an element within the entry block.

When you see a double hyphen, such as entry--type-post, it tells us that type-post is a modifier for entry.

All we’re doing is tying each piece of this block to the entry name. I hope the name “Block-Element-Modifier” makes more sense now. Just think of it as Block__Element--Modifier.

This separation with double underscores and hyphens is a great visual cue that tells a developer everything they need to know about a class and the block that it’s related to. With just a little use of the system, you should be able to quickly pick up on how things are related.

You could very well do this with a system of single hyphens. However, things can quickly become unclear if there’s several blocks or elements with similar names. Or, it’s tough to figure out if something is an element or modifier. BEM gives you a clear structure where you can immediately see what a class is used for. And, when you’re working with large teams of people, having a standardized system makes everyone’s workflow much more efficient.

Styling BEM classes

I use Sass (SCSS), but BEM works just as well with LESS, Stylus, or any CSS-preprocessor of your choosing.

Here’s a quick look at what an entry.scss file would look like (note that I house all of my entry-related code in one file):

.entry {

    &--post {}

    &__header {}

    &__title {}

    &__byline {}

    &__content {}
}

In Sass, the & will prepend the .entry to the front of the selector. So, &__title becomes .entry__title. When that gets compiled, it’d look like the following CSS:

.entry {}

.entry--post {}

.entry__header {}

.entry__title {}

.entry__byline {}

.entry__content {}

The reason I’m showing you this is that I want you to see that we don’t have any nested selectors there. Everything is namespaced and flat. This means that it’s far easier to overwrite somewhere down the line.

Pretty sweet, right?

As a theme reviewer, I often see nested selectors like:

.entry .post-header .title {}

That’s just a bad naming scheme anyway. Even if not using BEM, that can be cleaned up. But, BEM gives you a widely-used standard to follow.

The benefit for child themes

If you release themes to the public, you will absolutely have users who want to make design adjustments or other theme authors who are making child themes.

When you rely on nested selectors to style your theme, it becomes much harder to make changes. It makes creating child themes tougher because child theme authors must also often write nested selectors to overrule your code.

A good rule of thumb is to never nest more than two levels deep. When you start going beyond that, things can quickly get out of hand. BEM helps you keep things flat and those nests in check.

Concerns and questions

The following are some concerns and feedback I’ve seen about BEM.

The classes are ugly.

Yes, when you first see something like entry__title or entry--type-post, it can be a bit ugly. When I first saw it, I thought there was no way I’d be comfortable using it.

After using it for one project, I realized how nice it was (especially combined with Sass) to immediately understand the relationship between each piece of a block/component without having to dig through my HTML code.

BEM is for people who don’t understand CSS.

Understanding the “Cascading” aspect of Cascading Style Sheets (CSS), can actually be tough for some theme authors to grasp (we actually use the ITCSS organizational system to help with that, but I’ll save that for another post). When you’re working on large projects, it can even knock some of the best developers down a peg or two.

BEM is very much for people who have a grasp of the features and limitations of CSS. It means having enough experience to understand where a good naming system compliments the language and doesn’t hinder workflow or productivity.

BEM is a crutch.

If having a logical, organized naming scheme for classes is a crutch, so be it. If that crutch is going to help me write clean, component-based CSS without a lot of nested selectors, I’ll happily hobble along, crutch in hand.

BEM is a fad.

I don’t really buy into fads. Our group spent months covering many different systems in depth when building Mythic. Nothing was set in stone when I started the project. BEM was what we went with based upon discussion from developers with varying skillsets and backgrounds. Everyone seems to have picked it up with ease because it is a clear naming system that follows simple rules.

BEM is overly complex.

BEM is just a few rules for naming classes based on your existing code structure. If anything, it would simplify how you name classes by providing a standard.

block, block__name, block--modifier is pretty simple.

You can actually do more complex things like block__element--modifier when needing a modifier for an element, and we certainly do that in a few cases. But, I generally shy away from modifiers on elements where possible.

Mythic loves BEM

When I began this project, I wanted a standard naming system that I could use across all of my theme projects. I didn’t want to waste time naming things each time I created a new theme. It’s a big time suck that would be better spent on building out the design.

I’ve seen a lot of starter themes over the years, but most of them don’t address markup and class names in any meaningful way. Having a standard structure and naming scheme is the backbone of any theme design. Theme authors should be able to immediately open the SCSS/CSS and begin writing style rules.

Mythic takes this one step further and already has the component folders in place for you with the selectors sitting there. You merely have to plug in your rules.

8 Comments

  1. sky
    ·Reply

    It is pretty sweet! Thanks for explaining that so thoroughly. If your work will be built upon or extended by others in any way, they will be thankful that you used such a thoughtful approach.


  2. ·Reply

    Hey Justin,

    If you were to go another level deep, what would the BEM name be? For example:

    Written by Justin Tadlock

    I’m assuming .entry__byline span {} wouldn’t be correct in this system.

    .entry__byline—name?


    1. ·Reply

      You’d use .entry__name. For example, you might have .entry__author, .entry__date, and so on. Element names are built from the block.


    2. ·Reply

      I was on my phone earlier and couldn’t go into as much detail (I’m not a great phone typist).

      BEM doesn’t care about hierarchy. It’s all about the block/component. Let’s take a look at the following structure.

      <article class="entry">
          <header class="entry__header">
              <div class="entry__byline">
                  Written by <span class="entry__author">Justin Tadlock</span>
              </div>
          </header>
      </article>
      

      It keeps the class names flat, regardless of the structure. .entry__author is an element within .entry. It doesn’t matter that it’s also nested within .entry__byline, which is itself nested within .entry__header.

      Let’s look at a different example. Sometimes, some “elements” should be separated into their own “blocks”. I do this with comments:

      <section class="comments">
          <h2 class="comments__title">100 comments</h2>
          <ol class="comments__list">
              <li class="comment"></li>
          </ol>
      </section>
      

      Instead of .comments__comment, I use .comment because it is going to be a distinct block on its own with several elements.

      Being able to recognize what is a distinct block vs. what is just an element of another block is half the battle. Sometimes, it’s obvious. Sometimes, it’s a personal choice. On the whole, most Web site elements are pretty easy to break down into blocks.

      1. In reply to Justin Tadlock
        ·Reply

        Awesome! That really clarifies it for me, thanks Justin.


  3. ·Reply

    It is definitely good to use it in the large project. But, How to add support for the 3rd party plugins?


    1. ·Reply

      There’s really not much you can do with third-party plugins.

      One of the biggest problems with WordPress is that it doesn’t go far enough setting coding standards for theme and plugin authors.

      The bigger plugins that have a lot of front-end output should really be following some sort of class-naming system. And, if they’re not, it’s really up to us theme authors to push them to adopt a standardized system.

Leave a Reply

Your email address will not be published. Required fields are marked *