BEM is abbreviation for Block-Element-Modifier. It's a methodology that can help you to organize your CSS codebase - doesn't matter if you are one person or a project team. Check why, how and how not to use it.
Basics
Syntax consists of the following pattern:
block__element--modifier
block
component wrapper (required)__element
child element inside block (optional)--modifier
block or element variants (optional)
Examples
Following example contains basic rules that need to be kept in your mind.
index.html
<a href="#" class="btn btn--danger">
<span class="btn__ico">x</span>
</a>
<a href="#" class="btn btn--success">
<span class="btn__ico btn__ico--small">x</span>
</a>
style.css
// Block
.btn {
display: inline-block;
background: white;
}
// Modifier
.btn--danger {
background: red;
}
.btn--success {
background: green;
}
// Element
.btn__ico {
display: inline-block;
font-size: 0.8em;
}
// Element + Modifier
.btn__ico--small {
font-size: 0.6em;
}
style.scss
// Block
.btn {
display: inline-block;
background: white;
// Modifier
&--danger {
background: red;
}
&--success {
background: green;
}
// Element
&__ico {
display: inline-block;
font-size: 0.8em;
// Element + Modifier
&--small {
font-size: 0.6em;
}
}
}
One of the most common mistakes is to create multiple element nesting.
<a href="#" class="btn btn--danger">
<span class="btn__ico">
<!-- wrong -->
<span class="btn__ico__text">..</span>
</span>
</a>
// wrong
.btn__ico__text { .. }
The right solution is to create flattened structure without multiple nesting.
<a href="#" class="btn btn--danger">
<span class="btn__ico">
<!-- good -->
<span class="btn__text">..</span>
</span>
</a>
// good
.btn__text { .. }
Advanced
Once you start to create real applicaton with BEM some decisions issues probably appears. Read more to find out the most common ones.
Don't mix components
If there is already button btn
component, don't create new one like article__btn
.
<div class="article">
<div class="article__text">..</div>
<!-- wrong -->
<div class="btn btn--small article__btn"></div>
</div>
<div class="article">
<div class="article__text">..</div>
<!-- good -->
<div class="btn btn--small btn--secondary"></div>
</div>
Don't create component dependent on the context
If you need btn
component to have specific behaviour inside another article
component,
create new modifier covering other required cases.
.btn { .. }
.article {
// wrong
.btn { .. }
}
.btn {
// good
&--another { .. }
}
.article { .. }