BEM Naming

Updated at 2014-12-24 02:25

This note is about BEM CSS class naming methology.

BEM stands for Block Element Modifier. These three parts make up each class name.

Blocks contain elements. Class names start with a block definition and may optionally have one or multiple element definitions. Blocks and elements are separated by double underscores __.

.block {}                    /* Component, a well defined visual context. */
.block__element {}           /* A descendent element of a component. */
.block__element__element {}  /* A descendent element of an element. */

Each block and element may have one modifier. Modifiers are separated with double dashes --. Having multiple modifiers for a single block or element is not allowed.

.block--modifier {}          /* Component has multiple states. */
.block--modifier__element {} /* Component state affects child elements. */
.block__element--modifier {} /* Child elements have multiple states. */
.block__element--modifier__element {} /* You get the idea. */

Block, element and modifier names are in dashed lower case.

.person-profile {}
.person-profile--male {}
.person-profile--female {}
.person-profile__hand {}            /* Profile has a hand element. */
.person-profile--female__hand {}    /* Female hand has a special visual. */
.person-profile__hand--left {}      /* Left hand has a special visual. */

BEM takes more time to write, but helps future development. When naming classes like this, you understand how classes are related by reading the class names in the HTML.

<form class="site-search site-search--full">
    <input type="text" class="site-search__field">
    <input type="Submit" value ="Search" class="site-search__button">

You can mix standalone rules with BEM. Standalone rules should be written so that they work in all contexts (blocks).

.baseline-top { margin-top: 10px; }
.baseline-bottom { margin-bottom: 10px; }

js-* classes shouldn't have any visual style. All JavaScript hook CSS classes start with js- and shouldn't have any definition in the CSS files. They are only meant to be used by JavaScript. Also, JavaScript shouldn't search for any DOM elements without targeting the js- prefix, but may add and remove any classes.

<!-- Find this DOM element with '.js-date-select', never `.date-select` -->
<div class="js-date-select date-select"></div>
<!-- Manipulating classes in JavaScript is ok. -->
<div class="js-date-select date-select date-select--highlight"></div>