BEM your CSS

 

BEM your CSS

 
  • CSS selectors become expensive!
  • What is BEM?
  • Why using BEM?
  • How to use BEM with Sass?
 

CSS selectors become expensive!

 

With expensive we mean in the sense of performance or overwriting:

  • The more levels your selector has, the more time it takes to reach your element and can apply the style.
  • The more levels your selector has, the more difficult it is to debug.
  • The higher the specificity the selector is, the more difficult to overwrite and debug it is. 
 

What does it mean?

 

CSS selectors become expensive!

 

1 level selector

 

Example

 
.this-one-class {
    color: #ccc;
}
.grandfather.is-deaf .grandfather .son .grandchild {
    color: #ccc;
}

VS

 

5 levels selector

 

Which one is the most expensive? And takes more time to find the element?

 

CSS selectors become expensive!

 

1 level selector

 

Example

 

Expensive selector!

Harder to read and maintain

 
.this-one-class {
    color: #ccc;
}
.grandfather.is-deaf .grandfather .son .grandchild {
    color: #ccc;
}

VS

 

5 levels selector

 

CSS selectors become expensive!

 

1 level selector

 

Example

 
#section {
    color: #ccc;
}
.grandfather .grandchild {
    color: #ccc;
}

VS

 

2 levels selector

 

Which one is the most expensive? And takes more time to find the element?

 

CSS selectors become expensive!

 

1 level selector

 

Example

 
#section {
    color: #ccc;
}
.grandfather .grandchild {
    color: #ccc;
}

VS

 

2 levels selector

 

#ID selectors makes it expensive for debugging or overwriting.

 

More lightweight, easier to debug, easier to maintain

 

CSS selectors become expensive!

 

1 level selector

 

Example

 
.home-section {
    color: #ccc;
}
nav.navigation ul.grandchild li a {
    color: #ccc;
}

VS

 

6 levels selector

 

Which one is the most expensive? And takes more time to find the element?

 

CSS selectors become expensive!

 

1 level selector

 

Example

 
.home-section {
    color: #ccc;
}
nav.navigation ul.grandchild li a {
    color: #ccc;
}

VS

 

2 levels selector

 

Gives context, easy to overwrite or maintain

 

Selectors with elements and classes are very expensive. If elements are not in html, style does not apply

 

CSS selectors become expensive!

 

Browsers vs Humans

 

How a human read your selector:

 
nav ul li a
a li ul nav

How a browser read your selector:

 

CSS selectors become expensive!

 

Where browsers start

 
<nav>
    <ul>
        <li>
            <a href="#">Link</a>
        </li>
    </ul>
</nav>
nav 
ul 
li 
a

4.

3.

2.

1.

 

A browser start with the latest character and ends with the first

 

What is BEM

 

BEM stands for

 

BlockElementModifier

 
  • ...an CSS naming convention
  • ...an helper for you CSS classes
  • ...a way of structure your CSS classes
 

BEM is....

 

What is BEM

 
.btn {}
<a href="#" class="btn">Button</a>

CSS

 

HTML

 
.navigation {}
<nav class="navigation"></nav>
.footer {}
<footer class="footer"></footer>

Block component

 

Block components are removable in one piece and are for a spexific purpose or use.

1

What is BEM

 

Element

 
.btn__icon {
    font-size: 1em;
    color: #000000;
}
<a href="#" class="btn">
    <i class="btn__icon"></i>
</a>

CSS

 

HTML

 
.navigation__list {}
.navigation__list-item {}
.navigation__link {}
<nav class="navigation">
    <ul class="navitgation__list">
        <li class="navigation__list-item">
            <a href="#" class="navigation__link">
        </li>
    </ul>
</nav>

Element that depends upon the block. Separated from the block with "__".

1

What is BEM

 
.btn__icon {
    font-size: 1em;
}
.btn__icon--small {
    font-size: 0.5em
}
<a href="#" class="btn">
    <i class="btn__icon--small"></i>
</a>

CSS

 

HTML

 
.navigation__link--active {
    background-color: red;
}
<nav class="navigation">
    <ul class="navitgation__list">
        <li class="navigation__list-item--active">
            <a href="#" class="navigation__link">
        </li>
    </ul>
</nav>

Modifier

 

The modifier changes the style of a block or element. Separated from the block with "--"

1

What is BEM

 
.navigation__link--transparant {
    background: transparant;
}

Block (context)

Element

 

Modifier

 

This is BEM

 

Why use BEM

 
.nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.nav ul ul  {
  padding-left: 1em;
}
.nav ul li {
  float: left;
}
.nav ul li a {
  font-weight: 600;
  color: #000000;
  background: #ccc;
  display: inline-block;
  padding: 0.5em;
}
.nav ul li ul li a {
  background: #000000;
  color: #cccccc;
}
<nav class="nav">
    <ul>
        <li><a href="#">link</a></li>
        <li><a href="#">link</a></li>
        <li><a href="#">link</a></li>
        <li>
            <a href="#">link</a>
            <ul>
                <li><a href="#">link</a></li>
                <li><a href="#">link</a></li>
            </ul>
        </li>
    </ul>
</nav>

When you start with CSS

 

When you start with writing CSS, you get used to nesting to give context. This was very bad for maintainability and readability.

1

Why use BEM

 
.nav .list,
.nav .subnav {
  margin: 0;
  padding: 0;
  list-style: none;
}
.nav .list .subnav  {
  padding-left: 1em;
}
.nav .list .item {
  float: left;
}
.nav .list .item a {
  font-weight: 600;
  color: #000000;
  background: #ccc;
  display: inline-block;
  padding: 0.5em;
}
.nav .list .subnav .item a {
  background: #000000;
  color: #cccccc;
}
<nav class="nav">
    <ul class="list">
        <li class="item"><a href="#">link</a></li>
        <li class="item"><a href="#">link</a></li>
        <li class="item"><a href="#">link</a></li>
        <li class="item">
            <a href="#">link</a>
            <ul class="subnav">
                <li class="item"><a href="#">link</a></li>
                <li class="item"><a href="#">link</a></li>
            </ul>
        </li>
    </ul>
</nav>

Then your getting better

 

Then you become better. You start with giving more elements classes for readability and maintainability.

1

Why use BEM

 
.list--reset {
  margin: 0;
  padding: 0;
  list-style: none;
}
.navigation__sub-list  {
  padding-left: 1em;
}
.navigation__item {
  float: left;
}
.navigation__link {
  font-weight: 600;
  color: #000000;
  background: #ccc;
  display: inline-block;
  padding: 0.5em;
}
.navigation__sub-list .navigation__link {
  background: #000000;
  color: #cccccc;
}
<nav class="navigation">
    <ul class="navigation__list list--reset">
        <li class="navigation__item"><a href="#" class="navigation__link">link</a></li>
        <li class="navigation__item"><a href="#" class="navigation__link">link</a></li>
        <li class="navigation__item"><a href="#" class="navigation__link">link</a></li>
        <li class="navigation__item">
            <a href="#" class="navigation__link">link</a>
            <ul class="navigation__sub-list list--reset">
                <li class="navigation__item"><a href="#" class="navigation__link">link</a></li>
                <li class="navigation__item"><a href="#" class="navigation__link">link</a></li>
            </ul>
        </li>
    </ul>
</nav>

And there was BEM!

 

Someone tells you to checkout BEM, your gonna love it! It is gonna give readability, structure and maintainability.

1

Why use BEM

 
.list--reset {
  margin: 0;
  padding: 0;
  list-style: none;
}
.navigation__sub-list  {
  padding-left: 1em;
}
.navigation__item {
  float: left;
}
.navigation__link {
  font-weight: 600;
  color: #000000;
  background: #ccc;
  display: inline-block;
  padding: 0.5em;
}
.navigation__sub-list .navigation__link {
  background: #000000;
  color: #cccccc;
}

Before & After

 
.nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.nav ul ul  {
  padding-left: 1em;
}
.nav ul li {
  float: left;
}
.nav ul li a {
  font-weight: 600;
  color: #000000;
  background: #ccc;
  display: inline-block;
  padding: 0.5em;
}
.nav ul li ul li a {
  background: #000000;
  color: #cccccc;
}

What are the differences?

 

Why use BEM

 
.list--reset {
  margin: 0;
  padding: 0;
  list-style: none;
}
.navigation__sub-list  {
  padding-left: 1em;
}
.navigation__item {
  float: left;
}
.navigation__link {
  font-weight: 600;
  color: #000000;
  background: #ccc;
  display: inline-block;
  padding: 0.5em;
}
.navigation__sub-list .navigation__link {
  background: #000000;
  color: #cccccc;
}

Before & After differences

 
  • Most selectors became single class selectors
  • A class has his own context
  • More readable
  • More maintainable
 
.nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.nav ul ul  {
  padding-left: 1em;
}
.nav ul li {
  float: left;
}
.nav ul li a {
  font-weight: 600;
  color: #000000;
  background: #ccc;
  display: inline-block;
  padding: 0.5em;
}
.nav ul li ul li a {
  background: #000000;
  color: #cccccc;
}

Why use BEM

 

BEM benefits

 

1. Helps to write self defining context class selectors.

 

2. A class is most of the time not depended on the parent element or class.

 

3. Non-developers can read the code and tell where it is about!

 

How to use BEM with Sass

 

Example:

 
// Block
$module: 'navigation';
.#{$module} {

    // Element
    &__item {
        border-top: 1px solid #ccc;
    }
    
    // Modifier
    &--sub {
        margin-left: 15px;
        .#{$module}__link {
            font-style: italic;
        }
    }
}
.navigation__item {
    border-top: 1px solid #ccc;
}
.navigation--sub {
    margin-left: 15px;
}
.navigation--sub .navigation__link {
    font-style: italic;
}

Sources

 

BEM your CSS

By Raymon Schouwenaar