CSS Architecture Block-Element-Modifier (BEM)

The following is an extract from our book, CSS Master, written by Tiffany Brown. Copies are sold in stores worldwide, or you can buy it in ebook form here.

BEM, or Block-Element-Modifier, is a methodology, a naming system, and a suite of related tools. Created at Yandex, BEM was designed for rapid development by sizable development teams. In this section, we’ll focus on the concept and the naming system.

BEM methodology encourages designers and developers to think of a website as a collection of reusable component blocks that can be mixed and matched to create interfaces. A block is simply a section of a document, such as a header, footer, or sidebar, illustrated in Figure 2.3. Perhaps confusingly, “block” here refers to the segments of HTML that make up a page or application.

Figure 2.3. A home page might have header, main, and footer blocks

Blocks can contain other blocks. For example, a header block might also contain logo, navigation, and search form blocks as seen in Figure 2.4. A footer block might contain a site map block.

An element is a part of a block that performs a certain function. Elements are context-dependent: they only make sense in the context of the block they belong to.

A search form block, for example, contains a text input element and a submit button element, as evident in Figure 2.5. To clarify, we’re using “element” in the design element sense rather than the HTML element sense.

Figure 2.5. A search block with text input and submit button elements

A main content block, on the other hand, might have an article list block. This article list block might contain a series of article promo blocks. And each article promo block might contain image, excerpt, and Read More elements, as presented in Figure 2.6.

Figure 2.6. A promotional block for a website article

Together, blocks and elements form the basis of the BEM naming convention. According to the rules of BEM:

Block names must be unique within a project.

Element names must be unique within a block.

Variations of a block―say, a search box with a dark background―should add a modifier to the class name.

Block names and element names are usually separated by a double underscore (.block__element). Block and element names are typically separated from modifier names by a double hyphen (for example, .block--modifier or .block__element--modifier).

In both our markup and CSS, search--inverse and search__label--inverse are additional class names. They’re not replacements for search and search__label. Class names are the only type of selector used in a BEM system. Child and descendant selectors may be used, but descendants should also be class names. Element and ID selectors are verboten. This ensures that selector specificity remains low, selectors are without side effects, and CSS is independent of markup patterns. Enforcing block and element name uniqueness also prevents naming collisions, which can become a problem among teams.

There are several advantages to this approach:

it’s easy for new team members to read the markup and CSS, and understand its behavior

adding more developers increases team productivity

consistent naming reduces the possibility of class name collisions and side effects

CSS is independent of markup

CSS is highly reusable

There’s a lot more to BEM than what can comfortably fit in a section of a chapter. The BEM site describes this methodology in much greater detail, and also features tools and tutorials to get you started. To learn more about the naming convention aspect of BEM, another fantastic resource is Get BEM.

Tiffany B. Brown is a freelance web developer and technical writer based in Los Angeles. Brown offers web development and consulting services to larger agencies and small businesses. A former member of the Opera Software developer relations team, Brown is also co-author of SitePoint's JumpStart HTML5 book. She sporadically writes about web development technology on her blog. You can follow her on Twitter at @webinista.