# How to BEM
# What is BEM
BEM est une approche qui permet de nommer et d'organiser les classes CSS.
L'acronyme BEM correspond aux mots suivants : Block, Elements, Modifiers. Vous trouverez ci-bas la description de chaque terme, ainsi que quelques exemples pratiques.
Suite à votre lecture, il est conseillé de lire la documentation située au lien ci-dessous. Nous utilisons les approches BEM et ITCSS dans nos projets react.
# Block
Un Block correspond à un Composant ou à un Sous-Composant.
L'approche BEM requiert une certaine hiérarchie à l'intérieur d'un Block, c'est-à-dire qu'il faut fonctionner par niveaux :
block # Root of the component
├── block_element1
├── block_element2
│ ├── block_element2_element2.1
│ └── block_element2_element2.2
└── block_element3
<div class="cbx-v-block">
<div class="cbx-v-block_element1"></div>
<div class="cbx-v-block_element2">
<div class="cbx-v-block_element2_element2.1"></div>
<div class="cbx-v-block_element2_element2.2"></div>
</div>
<div class="cbx-v-block_element3"></div>
</div>
Exemple réel :
<aside class="cbx-v-alert">
<div class="cbx-v-alert_header">
<h1 class="cbx-v-alert_header_h1">Title</h1>
</div>
<div class="cbx-v-alert_body">Content</div>
<div class="cbx-v-alert_footer">
<button class="cbx-v-alert_footer_save-btn">Save</button>
<button class="cbx-v-alert_footer_close-btn">Close</button>
</div>
</aside>
Some important points
- There is an _underscore_ between each level.
- If a the name of a Block (or an Element) contains espaces, these must be replaced by a hyphen (
-). - For more information on prefixes (
cbx-v-), take a look a the ITCSS methodology.
# Elements
Un Element est une balise HTML comprise à l'intérieur d'un Block.
Nous avons déjà vu un exemple plus haut de la hiérarchie d'un Block, mais nous pouvons faire mieux. Regardons l'exemple ci-bas :
<nav class="cbx-v-nav">
<ul class="cbx-v-nav_list">
<li class="cbx-v-nav_list_item">
<a class="cbx-v-nav_list_item_link" href="#">
Home
</a>
</li>
<li class="cbx-v-nav_list_item">
<a class="cbx-v-nav_list_item_link" href="#">
Contact
</a>
</li>
</ul>
</nav>
Nous pouvons déjà observer une problématique assez importante : le nom de certaines classes commencent à être long.
Pour régler le problème, nous allons procéder ainsi :
<nav class="cbx-v-nav">
<ul class="cbx-v-nav_list">
<li class="cbx-v-nav_item">
<a class="cbx-v-nav_link" href="#">Home</a>
</li>
<li class="cbx-v-nav_item">
<a class="cbx-v-nav_link" href="#">Contact</a>
</li>
</ul>
</nav>
Cela demande de la pratique, mais l'idée est de raccourcir le nom d'une classe en enlevant les niveaux qui n'apportent auncune information pertinente.
# Modifiers
Un Modifier est une classe qui modifie l'état d'un Composant (d'un Block).
<!-- Single Modifier -->
<nav class="cbx-v-navigation -white">...<nav>
<!-- Multiple Modifiers -->
<nav class="cbx-v-navigation -white -open">...<nav>
Regardons, un exemple plus concret :
<button class="o-button">Text</button>
<button class="o-button -main">Text</button>
<button class="o-button -big">Text</button>
<button class="o-button -danger">Text</button>
<button class="o-button -small -warning">Text</button>
Ici nous avons plusieurs fois le même button, mais nous avons utilisé différents Modifiers afin de changer certains aspects visuels.
Jetons un coup d'oeil du côté du SASS.
.o-button {
// Size modifiers
padding: 1rem 2rem;
&.-small { padding: 0.5rem 1.5rem; }
&.-big { padding: 1.5rem 2.5rem; }
// Color modifiers
color:white;
background-color: gray;
&.-main { background-color: blue; }
&.-warning { background-color: orange; }
&.-danger { background-color: red; }
}
Les Modifiers peuvent agir sur plus d'une propriété et ils peuvent même changer complétement l'apprence d'un Composant.
Regardons un dernier exemple.
<nav class="cbx-v-navigation -white -fixed">
<ul class="cbx-v-navigation_list">
<li class="cbx-v-navigation_item">
<a class="cbx-v-nav_link" href="#">Home</a>
</li>
<li class="cbx-v-navigation_item">
<a class="cbx-v-nav_link -active" href="#">About</a>
</li>
<li class="cbx-v-navigation_item">
<a class="cbx-v-nav_link" href="#">Contact</a>
</li>
</ul>
</nav>
.cbx-v-navigation {
&.-fixed {
position: fixed;
top: 0;
left: 0;
}
width: 100%;
height: 5rem;
background-color: $black;
&.-white {
background-color: $white;
}
}
.cbx-v-navigation_list,
.cbx-v-navigation_item,
.cbx-v-navigation_link {
height: 100%
}
.cbx-v-navigation_list {
liste-style-type: none;
}
.cbx-v-navigation_item {
display: inline-block;
}
.cbx-v-navigation_link {
display:block;
padding: 1rem 2rem;
color: white;
.-white & {
color: $black;
}
&.-active {
background-color: $main-color;
}
}
Note : Les Modifiers commencent par un tiret.