CSS Architecture: Block-Element-Modifier (BEM) & Atomic CSS


The following is a short extract from Tiffany’s upcoming book, CSS Master, 2nd Edition, which will be available shortly.

We’ll now look at two methodologies for naming things in CSS. Both methods were created to improve the development process for large sites and large teams; however, they work just as well for teams of one. Whether you choose one or the other, neither, or a mix of both is up to you. The point of introducing them is to help you to think through approaches for writing your own CSS.

Block-Element-Modifier (BEM)

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 below. Perhaps confusingly, “block” here refers to the segments of HTML that make up a page or application.

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

A header block that contains logo, navigation, and search blocks

More granular than a block is an element. As the BEM documentation explains:

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_title. (To clarify, we’re using “element” in the design element sense rather than the HTML element sense.)

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 below.

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).

Here’s what BEM looks like using a search form example:

<form class="search">
    <div class="search__wrapper">
        <label for="s" class="search__label">Search for: </label>
        <input type="text" id="s" class="search__input">
        <button type="submit" class="search__submit">Search</button>
    </div>
</form>

A variation of this form with a dark background might use the following markup:

<form class="search search--inverse">
    <div class="search__wrapper search__wrapper--inverse">
        <label for="s" class="search__label search_label--inverse">Search for: </label>
        <input type="text"  id="s" class="search__input search__input--inverse">
        <button type="submit" class="search__submit search__submit--inverse">Search</button>
    </div>
</form>

Our CSS might look like this:

.search {
    color: #333;
}
.search--inverse {
    color: #fff;
    background: #333;
}
.search__submit {
    background: #333;
    border: 0;
    color: #fff;
    height: 2rem;
    display: inline-block;
}
.search__submit--inverse {
    color: #333;
    background: #ccc;
}

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. Enforcing block and element name uniqueness also prevents naming collisions, which can become a problem among teams.

There are several advantages to this approach:

The post CSS Architecture: Block-Element-Modifier (BEM) & Atomic CSS appeared first on SitePoint.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *