Earlier this year, we launched a new gap intelligence website. It had been awhile since the previous design and it was time for a refresher. What initially was intended to be a re-working of the previous site, turned out to be a tear-down and rebuild from the ground up. We decided that if we were going to do it, we were going to do it right. This meant well thought-out approaches and execution on every level. From a front-end development perspective, this meant a mobile-first responsive design utilizing Bootstrap, HTML5, CSS3, CSS3 effects/animations, Sass, Javascript/jQuery, icon fonts, SVG images, and last but not least… a CSS framework.
CSS Frameworks
If you're unfamiliar with CSS frameworks, they are essentially a methodical approach to naming, structuring, and modularizing your CSS. CSS has no inherent organizational rules and no recommendations from the W3C. This means that for most of the web's life, CSS has been running free, wild, and leaving a splattered mess of styles and classes in it's wake. The notion of establishing CSS frameworks started in 2009 with Nicole Sullivan's OOCSS (Object Oriented CSS). Since the birth of OOCSS, many frameworks have surfaced, attacking the issue from different angles, but all with the same end goal of structured, manageable, scalable, modularized CSS. Currently, the most popular frameworks are:
- Nicole Sullivan's OOCSS (Object Oriented CSS)
- Jonathan Snook's SMACSS (Scalable Modular Architecture for CSS)
- Yandex's BEM (Block, Element, Modifier)
You may ask yourself, "Do I really need a framework?" Well… have you ever found yourself:
- In a complex maze of
!important
rules that are seemingly held together with duct tape? - Writing styles that won't overwrite other styles because of specificity issues?
- Creating new styles when those styles already exist elsewhere in your unorganized CSS?
- Debugging another dev's work and spending far too much time figuring how the code works?
- Wishing you could arrange (and rearrange) scalable chunks of code like Lego blocks within your project without them breaking?
- Needing the ability for multiple devs to work simultaneously on a single CSS file?
- Hoping that your back-end devs have the ability to create properly named styles and classes when you're on vacation?
If you answered yes to any of these, which I'm sure you did, you'll probably want to keep reading.
Why BEM?
Why the focus on BEM and not OOCSS, SMACSS, or any other framework? Because I've found BEM to work best for gap intelligence's projects and for my mode of thinking. There are pros and cons to every framework, but here's why I use BEM over it's competition.
Pros
- The creation of modular front-end code with strict, clearly defined naming conventions – OOCSS and SMACSS are a little loose and abstract. Looking at OOCSS projects, I can often find ambiguous swaths of code.
- The predefined naming conventions make naming easier and more logical – which is often one of the most difficult front-end tasks.
- The naming conventions clearly describe what classes are doing and makes it easier for other devs to debug and understand what your code is doing.
- The flattening of CSS selectors and classes makes subclassing easier. This also ties into the massive bonus of making specificity, a potentially complex issue, a non-issue.
- It's scalability and benefits apply to projects of all sizes.
Cons
- It's class names can be long and "ugly" – as I've often read online.
Honestly, that's the only "con" I could muster. Even more honestly, the concern should be with how effectively our classes function and communicate information rather than how they look. After all, isn't logical, predictable, scalable, modular code a beautiful thing?
What Does BEM Mean?
BEM stands for "Block, Element, Modifier." Essentially every web layout can be broken into encapsulated modules, or blocks, as BEM calls them. You can then rearrange these blocks as you see fit to easily create or update layouts. Examples of reusable blocks could be your site's nav
, logo
, search
, tabs
, footer
, etc.
Photo Credit: smashingmagazine.com
Blocks can also be inside of other blocks. In the above graphic you can see that the logo
, search
, and login
blocks are inside the tabs
block.
BEM Naming Convention
BEM all comes together and shows it's worth when you start using it's naming convention. The naming convention pattern is as follows:
.block {}
.block__element {}
.block__element--modifier {}
.block--modifier {}
.block
is the parent container or highest level of the block..block__element
is an element of the block. Elements are denoted by two underscores..block__element--modifier
is a modifier of the element of the block. Modifiers are denoted by two dashes..block--modifier
is a modifier of the block. Modifiers can be applied to both elements and blocks.
BEM in Practice
Let's use a person as an example for how this works in practice. I'll describe the person, their head, and parts of their face using BEM.
Below is the base HTML for our .person
block. "Base" meaning this is the reusable starting block for all future modified .person
blocks.
<div class="person">
<div class="person__head>
<div class="person__nose"></div>
<div class="person__mouth">
<div class="person__teeth"></div>
</div>
</div>
</div>
And below is one of those future modified .person
blocks I just mentioned. I've subclassed the base HTML with BEM modifier classes – thereby creating a whole new .person
block. It's a huge benefit and timesaver that I'm able to quickly reuse and repurpose blocks of code and their styles in this manner – as well as describe one scary ass clown from my childhood.
<div class="person person--male">
<div class="person__head person__head--white>
<div class="person__nose person__nose--red"></div>
<div class="person__mouth">
<div class="person__teeth person__teeth--sharp"></div>
</div>
</div>
</div>
Now That You've Seen BEM in Action
Hopefully at this point, you're seeing some of the benefits of using BEM. Taking a look again at the .person
block you'll notice:
- The BEM approach created modular front-end code with consistent and predictable naming conventions.
- The strict naming convention allows for easier class naming by you and quicker debugging by others not familiar with your code.
- The modularity of blocks allow you to move them around your project without breaking.
- The modularity of the framework allows for multiple devs to work simutaneously on the same stylesheet – assuming they agree on which blocks they are working on beforehand.
- Because of subclassing and flattening of styles, your CSS will be free of frustrating specificity issues.
- The framework is scalable and it's benefits apply to projects of all sizes.
All of these points are huge wins in my book and worth the time to learn and adopt BEM – or any other CSS framework for that matter. Since adopting BEM, I've never been able to look at my pre-BEM CSS the same way again. That's one of the things I love about this work though – you are never done learning.