Experience Management

Using BEM-Style CSS Syntax in SCSS

Modular component styles are becoming significantly important in modern UI trends. Handling scalability while decreasing naming convention differences is a necessary step towards code cohesion.
Disclaimer: I use a slightly modified flavor of BEM syntax, feel free to use traditional BEM, or some other flavor of your own.
When developing UI components, specifically for use in CMS or other modular platforms, it becomes necessary to organize your components’ styles. Naming conventions of components will become more important, both as more developers begin touching the same codebase, and as the codebase’s size and complexity grows.
To combat issues that arise from multiple developers and a growing list of components, we have to begin standardizing our components. This is where a CSS methodology like BEM comes into play. With BEM syntax, we can all use a common naming convention in all of our components. This way, any one developer can modify and make changes to any other developer’s work.
BEM syntax is a naming convention for CSS classes. BEM has 3 parts to its naming structure:

  • Blocks: encapsulate and comprise components
  • Elements: pieces of components that are specific to that component
  • Modifiers: additional states of elements that modify their appearance

I won’t get into the specifics of the BEM prescribed name rules, but I encourage you to familiarize yourself with them.
As mentioned above, I don’t use as strict set of rules as BEM dictates. The major difference is that I prefer to denote more of a tree structure:
HTML

<div class="promo">
    <div class="promo--background"></div>
    <div class="promo--content">
        <div class="promo--content--header">...</div>
        <div class="promo--content--info">...</div>
        <div class="promo--content--cta">...</div>
    </div>
</div>
The Digital Essentials, Part 3
The Digital Essentials, Part 3

Developing a robust digital strategy is both a challenge and an opportunity. Part 3 of the Digital Essentials series explores five of the essential technology-driven experiences customers expect, which you may be missing or not fully utilizing.

Get the Guide

This might make for longer and more verbose class names, and I don’t recommend you get too crazy and literally build a selector from every leaf. In this example, I’d still have my .promo--title and .promo--subtitle inside of .promo--content--header and not name them .promo--content--header--title (that’s just ridiculous). The key here is that I use these “layers” where they make sense structurally, where the “element” that is being named lies within a “section” of the master “block.” I prefer to separate these structural “layers” by using double-hyphens, instead of the BEM prescribed double-underscore. The reasoning behind this comes down to code legibility, two hyphens are actually separated in a monospace font; where two underscores get ligitured together. This “double-dash” style makes classes’ layers more immediately parsable by human eyes.
I also prefer to just chain modifier classes:
HTML

<div class="promo square">...</div>

CSS

.promo.square {...}

This affords me the ability to style all elements similarly, while keeping the markup’s class-lists less cluttered.
As with any use of SCSS, there is an importance to keeping the SCSS legible and not nesting too deeply (so as not to create a specificity nightmare). However, when you componentize SCSS into modular pieces, it’s a good idea to keep your files organized. We have chosen to standardize on a “component-level” selector, and then nest concatenated selectors underneath it. The idea is that then every style needed for a given component is chunked beneath a single SCSS node.
SCSS

.promo {
    &--header {...}
    &--content {...}
    &--cta {...}
}

In this example, the chunk of SCSS that contains all the styles for the promo component are all nested underneath the single promo selector. Using the concatenation combinator can be dangerous for readability; it’s easy to get lost in the SCSS and wonder what selector the rule is actually applying to. For this reason, we’ve established that it’s necessary to comment every selector that uses the concatenation combinator (to change the selector).
SCSS

.promo {
    &--header { // .promo--header
        &.closed {...}
    }
}

In this example, we commented the .promo--header selector, but did not comment the &.closed selector, since the closed selector is just a modifier and doesn’t change the base selector. An added benefit of using the concatenation combinator is: theoretically, specificity stays relatively light all the way down the SCSS node tree; it becomes easier to manage specificity later, either by overriding or when you go to use media queries, mixins, etc.
TL;DR
SCSS is great. BEM makes sense, mostly. Use structural “layer” selectors. Nest selectors to modularize component styles. Use concatenation combinator to avoid specificity hell. Comment concatenated selectors to avoid readability issues. Don’t get crazy with the naming or nesting.
 
 

About the Author

More from this Author

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe to the Weekly Blog Digest:

Sign Up