BEM Basics

BEM Basics

Nelsol Batalla

August 01, 2014

The concept of CSS methodologies was pretty foreign to me for the first two years I spent building websites. During those early years, I approached coding CSS my way, a way that I understood and expected others to understand as well. It was not until I worked on my first team project that I realized my way was foreign to others.

Working on a code base that multiple hands have touched is difficult. Everybody has their own style that they impart onto the code. When combined with others on a team, our individual code styles can wreak havoc on the readability, maintainability, reusability, and scalability of a project's codebase. Establishing a methodology can mitigate some of these difficulties.

My first foray into CSS methodologies came in the form of OOCSS and SMACSS. Both methodologies aim to make CSS more scalable and maintainable; where they differ is in their implementation. On a broad level, OOCSS focuses on separation of structure from skin, and separating container from content. On the other hand, SMACSS focuses on categorization of code that falls under five distinct categories. A third CSS methodology, BEM, is part of a holistic approach to front-end development that I think is an interesting way to organize CSS and HTML components.

BEM stands for Block, Element, Modifier. It focuses on organizing sections of a website into purposeful blocks, which are comprised of their functional elements, and are then manipulated by modifiers. BEM also employs a hierarchical naming convention that allows a team of developers to uniformly and immediately understand the lay of the land.

Blocks

Blocks are standalone chunks of code that should be modular and contain their own sets of elements. Think of blocks as headers, sidebars, and footers—they are the major Lego pieces that you put together to build a website.

Defining a block in BEM convention is as simple as giving it a unique class name, like so:

.sign-up-form { ... }

This creates a class for a sign-up form, but it only becomes a BEM block when it has associated elements within it that follow BEM naming conventions, which I cover below. Otherwise it’s just a class that doesn’t fall into any BEM category.

By separating a website into unique identifiable class names, team members can more easily isolate which section of the code to tackle when design and technical requirements change. At its core, BEM wants you to quickly and easily ascertain what a piece of code is doing by simply looking at its given name. This is further accentuated when elements are added into the mix.

Elements

Elements are pieces of code that are associated to a block. The naming convention used for BEM elements make it easy to understand what the markup will look like. Take this code for example:

.sign-up-form {
		...
}
.sign-up-form__field {
		...
}
.sign-up-form__button {
		...
}

While the syntax looks a little funny and confusing at first, especially with the addition of double underscores, it is actually pretty easy once you get the lingo down. The double-underscores denote that the .sign-up-form__field and sign-up-form__button elements are children of the .sign-up-form block. It is small visual cues like these that make it easy to understand its relationship with the containing block. Here's what the markup would have looked like:

<form class="sign-up-form">
		<input type="text" class="sign-up-form__field" value="name">
		<input type="password" class="sign-up-form__field">
		<input type="submit" class="sign-up-form__button" value="name">
</form>

Coming up with names of classes is arguably one of the hardest things a developer has to deal with, and oftentimes we overthink it. In particular, I struggled with accepting class names that had the same prefixes (for example: .thread-wrapper, .thread-heading, .thread-title, .thread-list, and so on…). With BEM, this has become less of an issue because it is accepted within its convention.

Modifiers

Modifiers, as the term implies, modify the state of an element or block. When you have an element or block that shares similar styles and only needs a slight change, you use a modifier. Take this code for example:


<form class="sign-up-form">
				<input type="text" class="sign-up-form__field--pink" value="name">
				<input type="text" class="sign-up-form__field" value="email">
				<input type="text" class="sign-up-form__field" value="username">
				<input type="text" class="sign-up-form__field" value="phone">
				<input type="password" class="sign-up-form__field">
				<input type="submit" class="sign-up-form__button" value="name">
</form>

You'll notice that the first sign-up-form__field element has a double-hyphen followed by the word “pink.” This is the recommended syntax for a modifier. Admittedly, the syntax lacks elegance. But where it falls short in elegance, it makes up for in clarity.

There are several ways you can go about implementing this modifier in your CSS. The first utilizes SASS @extend to pull the same CSS properties into the new modifier class, like so:

.sign-up-form__field {
		/* Similar CSS Properties */
}

.sign-up-form__field--pink {
		@extend sign-up-form__field;
		background-color: pink;
}

What I like about this method is that it removes extra markup in your HTML. The downside is you'll have two CSS classes that have very similar properties when SASS compiles.

The alternative looks like this:

<form class="sign-up-form">
		<input type="text" class="sign-up-form__field sign-up-form__field--pink" value="name">
</form>

If you opt not to use SASS @extend, you'll instead have to apply an extra class in your HTML markup. This decision really comes down to personal taste. Personally, I prefer having less code in my CSS and would opt to add the extra class in my markup.

Give BEM A Chance

BEM is a good methodology for beginners or for projects with a high turnover rate because it’s very logical, and its naming convention makes the structure explicit throughout. But BEM is just one of many methodologies out there, and what matters most is not the specific methodology you use, but that you and your team choose a methodology that fits the project’s and team’s needs.