BEM

What is BEM

BEM stands for Block, Element, Modifier and is a way of writing CSS so that it is clear, concise, recognizable, and modular. BEM follows a set way of writing blocks of CSS to break them down into re-usable chunks of code, or not, as we will explain later. The BEM naming conventions mean that blocks and their child elements are easily identifiable.

One of the aims of BEM is to eliminate, or drastically reduce, the use of descendant selectors. Descendant selectors can slow your page load down, as browsers read them from right to left, take the following example: .nav > ul > li > ul > li > a the browser would begin with the "a" tag and start working backwards matching selectors as it goes, with BEM we would just give that "a" tag its own class, .sub-nav__link for example, and target it directly, this creates much flatter and faster rendering CSS, especially on larger sites.

In the following sections we will use a simple employee profile block as an example of how BEM works.

Blocks

Blocks are the starting point for all things BEM. To begin our Employee profile block, we will start by creating an outer wrapper, in BEM this is known as a Block.

Nothing special going on here, except, you will notice the class name may be longer than you are traditionally use to, this is one of the cornerstones of BEM methodology, class names that have meaning, and leave no doubt in the mind what they are used for, when constructing your class names, think to yourself "If someone was to see this code for the first time, would they know what it was for?".


<div class="employee-profile">
	
</div>

Elements

Elements are the next part of the BEM jigsaw. Elements reside inside blocks, and are not meant to have meaning outside of their block. Elements have their parent class name followed by a double underscore and their own name.

In our example we will create several elements for our employee block, a place for the employees name, their picture, and a brief bio.


<div class="employee-profile">
	<div class="employee-profile__name">
		<p>John Smith</p>
	</div>
	<div class="employee-profile__picture">
		<img src="john-smiths-picture.jpg" alt="A Picture of John Smith">
	</div>
	<div class="employee-profile__bio">
		<p>
			John has been with the company for 9 years,
			working in accounts, he manages the accounts of
			some of our largest clients.
		</p>
	</div>
</div>

Our CSS for the employee profile may look something like this:

Notice how the class names are very descriptive, following the BEM methodology, there can be no mistake that .employee-profile__name belongs inside .employee-profile as it carries a double underscore after its parents name, immediately identifying it as a child element.


.employee-profile {
	width: 100%;
	background-color: #f8f8f8;
	float: left;
	overflow: hidden:
}
.employee-profile__name {
	font-size: 18px;
	font-weight: bold;
}
.employee-profile__picture {
	display: block;
	display: block;
	margin-bottom: 15px;
	border: 1px solid #fff;
}
.employee-profile__bio {
	font-style: italic;
}

Here is what our employee block looks like so far.

Our markup is well structured, and our classes are descriptive, following BEM naming conventions.

John Smith

A Picture of John Smith

John has been with the company for 9 years, working in accounts, he manages the accounts of some of our largest clients.

Modifiers

Modifiers are designed to alter the look, or functionality of a block or element. Modifiers are identified as having a double hyphen preceding them. a modifier for our employee profile block could look like this employee-profile__picture--framed this modifier could be used to display a thick frame around the picture instead of the thin border used in our earlier example. Because BEM offers such a flat way of producing our CSS, over riding it with a modifier is a simple task.


<div class="employee-profile__picture employee-profile__picture--framed">
	<img src="john-smiths-picture.jpg" alt="A Picture of John Smith">
</div>

The CSS, including our new modifier would look like this:

Notice the lack of descendant selectors, our CSS is flat and well structured, using the BEM method you can dramatically cut, if not eliminate style seep from other areas.


.employee-profile {
	width: 100%;
	background-color: #f8f8f8;
	float: left;
	overflow: hidden;
	padding: 20px;
}
.employee-profile__name {
	font-size: 18px;
	font-weight: bold;
}
.employee-profile__picture {
	display: block;
	margin-bottom: 15px;
	border: 1px solid #fff;
}
.employee-profile__picture--framed {
	border: 8px solid #fff;
}
.employee-profile__bio {
	font-style: italic;
}

Once we have applied our modifier, we get the following result:

As you can see, we now have a thick white frame around our employees picture. Modifiers can be used to override blocks and elements in multiple different ways, all without touching the base styles of your block or element.

As you dig into your theme you will see that we have made extensive use of modifiers to create lots of different image hover states, using BEM modifiers we were able to build lots of different states and effects quickly and easily.

John Smith

A Picture of John Smith

John has been with the company for 9 years, working in accounts, he manages the accounts of some of our largest clients.

The power of BEM & SCSS

SCSS kicks BEM to a whole new level. With SCSS its possible to write your styles in such a way that lends itself to BEM perfectly. SASS/SCSS nesting has been around for a while, but straight nesting gives the unpleasant side effect of creating lots of descendant selectors, however by using the & symbol, SCSS will attach one selector to the end of another. Here is our employee profiles CSS written in SCSS.

By using this technique we only have to write our blocks class name once, we can then just attach our element names by using the & symbol, we can even nest our modifiers in the same way.


.employee-profile {
	width: 100%;
	background-color: #f8f8f8;
	float: left;
	overflow: hidden;
	padding: 20px;
	&__name {
		font-size: 18px;
		font-weight: bold;
	}
	&__picture {
		display: block;
		margin-bottom: 15px;
		border: 1px solid #fff;
		&--framed {
			border: 8px solid #fff;
		}
	}
	&__bio {
		font-style: italic;
	}	
}