# 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.