.componentName__elementName -modifierName
ABEM is a variant of BEM. Both are targeting and naming conventions for CSS.
BEM (Block, Element Modifier) is a convention for targeting and naming CSS. Using this convention makes our code more clear, more consistent, and more modular. It’s a popular and well documented, and pairs well with Atomic Design or other methodologies, as it it makes it easier to find which file a class is likely defined.
<a>
, <nav>
, or <button>
, you can use whatever BEM classes you’d like.Atomic Design defines a structure for organizing blocks. It’s well documented, flexible, and works well with our other tools and methodologies. It also promotes thinking about reuse first when building, encouraging developers to not only create reusable BEM blocks, but reuse the blocks in the creation of bigger, fancier blocks.
ABEM (Atomic BEM) is a slight variant of BEM that makes two important changes as well as slightly changing the syntax.
block-name__element-name--modifier-name
NS-blockName__elementName -modifierName
Here’s an example of markup using BEM:
<header class="site-header site-header--transparent site-header--fixed js-stickyHeader">
<a class="site-header__company-logo site-header__company-logo--dark-knockout">
<!-- -->
</a>
<nav class="site-header__primary-navigation">
<!-- -->
</nav>
<button class="site-header__call-to-action button button--primary button--large">
<!-- -->
</button>
<header>
And here’s it using ABEM:
<header class="siteHeader -transparent -fixed js-stickyHeader">
<a class="siteHeader__companyLogo -darkKnockout">
<!-- -->
</a>
<nav class="siteHeader__primaryNavigation">
<!-- -->
</nav>
<button class="siteHeader__callToAction button -primary -large">
<!-- -->
</button>
<header>
The notable features are:
js-stickyHeader
.)The choice to use ABEM is primarily for legibility. Code is read way more than it is written, and ABEM makes markup easier to read.
The following BEM conventions apply:
lowerCamelCase
version of its name.As well as the following ABEM conventions:
js-
. Boilerplate recommends that the js-
prefix is used to denote every class that’s used for targeting from JavaScript, and that these classes do not overlap with those used for styling.All a BEM mix is using multiple BEM blocks or elements on the same DOM element. For example, it’s fine for an element of one block to also be block itself:
<div class="feature">
<p>
Ipsum mollitia dolores quisquam minima obcaecati. Atque ipsam vel ex?
</p>
<button class="feature__callToAction button">Learn More</button>
</div>
It’s allowed to even use two different BEM blocks on the same DOM element, but generally that suggests that those two blocks should be combined or rethought.
In general, styling elements within blocks should be avoided, however, one typical exception is for styling elements that are just part of rich text.
For example
<div class="messaging -success">
<p>
Success! Your changes have been saved. <a href="#">View now.</a>
</p>
</div>
In this context, the <a>
tag is simply being used as part of rich text, but we may need to alter its text color while within .messaging.-dark
. Other common examples are when elements are part of content coming from a CMS, such as
<a>
tags within short descriptions,<h1>
through <h6>
) within news articles, and evenIn these instances - where you simply need to override the default styling for tags within rich text because of a parent component - it’s okay to style to element within the block:
.messaging.-success {
background-color: darkgreen;
a {
color: white;
text-decoration: underline;
}
}
The reason for this exception to better support styling generated HTML, such as CMS content, server messages, rich text API responses, etc.
If you’d like to define sass mixins or functions, Boilerplate recommends
lowerCamelCase
.