So what is BEM, and why can it help with reducing or removing CSS specificity issues?
BEM, or Block Element Modifier, helps us style elements using a systematic naming convention, which is structured thus:
.block: top-level containing the element we're going to change.block__modifier: the style assigned when the state of an element is changed.block__element: an element inside a top-level container.block__element__modifier: alternate representation of an element, when its state has been changedThe idea behind this style of coding is to make it portable and easier to maintain. The basis for this is that, while standard, non-BEM CSS is more concise, it is harder to infer what each rule does. We frequently have to assign multiple classes to an element, which introduces a degree of CSS specificity, and reduces the reusability of CSS rules. Using BEM allows us to combine the constituent names into one style class name, and remove any concern around CSS specificity.
If we use this concept, we can use it to write style rules such as this:
.block {
&__element {
}
&__modifier {
}
}This will compile to the following:
.block {}
.block__element {}
.block__modifier {}The preceding code uses plain BEM format, but from within a processor environment such as SASS to construct BEM rules in PostCSS, we can use the postcss-bem plugin (available from https://github.com/ileri/postcss-bem) to produce our BEM CSS using @-rules. For example:
@component ComponentName {
color: cyan;
@modifier modifierName {
color: purple;
}
@descendent descendentName {
color: darkred;
}
@when stateName {
color: yellow;
}
}In this instance, @component signifies our Block, @descendant our element, and @modifier is our modifier. When compiled, our CSS would look like this:
.ComponentName {
color: cyan;
}
.ComponentName--modifierName {
color: purple;
}
.ComponentName-descendentName {
color: darkred;
}
.ComponentName.is-stateName {
color: yellow;
}The beauty of using BEM is that it helps to reduce or even avoid CSS specificity issues—although names are longer, we can combine both element and modifier names into one class, instead of having to apply three or more separate classes. Granted, there may be instances where we might have to apply a second class, but with careful planning we should be able to reduce this to a minimum.
Right, onwards we go: let's get stuck in to coding! Over the next few pages, we will take a look at implementing BEM styling in a simple demo, and see how we can use PostCSS to compile our code.
For our BEM demo, we're going to work through the CSS rules required to show some simple message boxes on screen, such as for displaying confirmation that a task has completed, or a warning when something isn't right.
The original version of this demo, by Rene Spronk, is available from http://www.cssportal.com/blog/css-notification-boxes/.
It's a simple demo, but shows off the principles behind BEM CSS perfectly—go ahead and extract a copy of the Tutorial8 folder, then run index.html to get a feel for what we will be producing. This version uses standard CSS; we will use this as a basis for converting to using BEM.
Let's make a start:
Tutorial9 folder from the code download that accompanies this book—drop this into our project area..dlgBox {
border-radius: 0.625rem;
padding: 0.625rem 0.625rem 0.625rem 2.375rem;
margin: 0.625rem;
width: 14.5rem
}<span> element—this turns the lead-in caption for each dialog to uppercase and sets it in bold text:span { font-weight: bold;text-transform: uppercase; }@component content {@descendent of our @component: @descendent alert {
font-family: Tahoma, Geneva, Arial, sans-serif;
font-size: 0.6875rem;
color: #555;
border-radius: 0.625rem;
}:hover pseudo-element reduces the opacity when we hover over the box: @modifier error {
background: #ffecec url("../img/error.png") no-repeat 0.625rem 50%;
border: 0.0625rem solid #f5aca6;
}
@modifier error:hover { opacity: 0.8; } @modifier success {
background: #e9ffd9 url("../img/success.png") no-repeat 0.625rem 50%;
border: 0.0625rem solid #a6ca8a;
}
@modifier success:hover { opacity: 0.8; } @modifier warning {
background: #fff8c4 url("../img/warning.png") no-repeat 0.625rem 50%;
border: 0.0625rem solid #f2c779;
}
@modifier warning:hover { opacity: 0.8; } @modifier notice {
background: #e3f7fc url("../img/info.png") no-repeat 0.625rem 50%;
border: 0.0625rem solid #8ed9f6;
}
@modifier notice:hover { opacity: 0.8; }
}style.scss into the src folder of our top-level project area (and not into the Tutorial8 folder!).Our simple demo isn't going to set the world alight in terms of styling. If we were to preview it now, the results will of course not look great; let's fix that by setting up the compilation and linting tasks within PostCSS.
If you are a SASS user, then you can see a version of this code suitable for that processor on GitHub—the code is available at: https://gist.github.com/alibby251/45eab822a6a619467279. Note how similar the results are when you compare the compiled version with the version we'll get in the next exercise!
Our code is in place, but the boxes won't look particularly appetizing—most of the styles are still written using PostCSS @-rules. We can fix that by compiling the code, so let's dive in and take a look at installing support for BEM.
Setting up BEM support in PostCSS is a cinch—we can make use of two plugins to compile and lint our code. The plugins we need for this task are postcss-bem (available from https://github.com/ileri/postcss-bem), and postcss-bem-linter (available from https://github.com/postcss/postcss-bem-linter). Both can be installed using the same process through Node.js.
Hopefully the process will be familiar by now, so without further ado, let's make a start:
npm install --save-dev postcss-bem

postcss-bem-linter, using this command:npm install --save-dev postcss-bem-linter

Now that the plugin is installed, we can go ahead and add support to our gulp task file, and begin to parse our code:
gulpfile.js file at the root of our project area.gulpfile.js, at the root of our project area. We start with setting a number of variables that call each of the plugins:var gulp = require('gulp');
var postcss = require('gulp-postcss');
var bem = require('postcss-bem');
var bemLinter = require('postcss-bem-linter');
var reporter = require('postcss-reporter');gulp.task('lint', function() {
return gulp.src('dest/*.css')
.pipe(postcss([
bemLinter({ preset: 'bem' }),
reporter({ clearMessages: true })
]))
.pipe(gulp.dest('dest/'));
});gulp.task('bem', function() {
return gulp.src("src/*.css")
.pipe(postcss([bem({
style: 'bem',
separators: { descendent: '__' }
})]))
.pipe(gulp.dest('dest/'));
});gulp.task('default', ['bem', 'lint']);gulpfile.js with a watch facility, to kick in and compile our code when any changes are made to it:var watcher = gulp.watch('src/*.css', ['default']);
watcher.on('change', function(event) {
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});package.json file too—add these lines to a new file, and save it to the root of the project area. These simply tell gulp which versions of our plugins to use when compiling the code:{
"name": "postcss",
"version": "1.0.0",
"description": "Configuration file for PostCSS",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Alex Libby",
"license": "ISC",
"devDependencies": {
"gulp": "^3.9.0",
"gulp-postcss": "^6.0.0",
"postcss-bem-linter": "^2.0.0",
"postcss-reporter": "^1.3.0"
}
}style.css from the css – completed version folder under Tutorial9—save this to the src folder under our project area.gulp

dest folder into the css folder underneath Tutorial9—if all is well, we should see something akin to this screenshot when previewing the results in a browser:
Our simple demo shows some useful message boxes that we can use as a basis for something more complex; it illustrates perfectly how we can use BEM to style our code, while keeping issues around CSS specificity at bay. We've covered a few useful techniques throughout this exercise, so let's take a moment to explore them in more detail.