BEM – Block, Element, Modifier

03-12-2017

Lees hier een introductie op een vaak gebruikte front-end methodologie BEM. Veel websites zoals envato.com, bbc.com, theguardian.com, csswizardry.com, udemy.com en linkedin.com gebruiken de BEM methodologie. BEM staat voor Block, Element en Modifier en gaat voornamelijk in op de naamgeving van HTML en CSS elementen op een gestructureerde manier.  Het helpt front-end ontwikkelaars beter om de relatie tussen HTML en CSS te begrijpen. Daarnaast bevordert BEM de consistentie en de kwaliteit in de code.

Block

Het “block” is het basis component dat niet afhankelijk is van andere componenten. Het block is het buitenste deel van het component. Vaag jezelf af of het component op meerdere plekken gebruikt kan worden. Is het antwoord ja? Dan kun je ervan uitgaan dat je een block kunt gebruiken. Voorbeelden van block’s zijn header, footer, sidebar. Maar bijvoorbeeld ook logo, price, cart, item. In onderstaand voorbeeld zie je het price block.

.price {}
<span class=”price”></span>

Element

Het “element” is een onderdeel van het block. Het is afhankelijk van het block component. Een block kan meerdere elementen bevatten. In onderstaand voorbeeld zie je element van een price block. Een price kan bijvoorbeeld bestaan uit een valuta en uit een waarde. Elementen van een bepaald block benoem je door middel van de block naam gevolgd door het element met twee onderstrepingstekens (__) als prefix.

.price__currency {}
.price__value {}
<span class=”price”>
<span class=”price__currency”>€</span>
<span class=”price__value”>10,00</span>
</span>

Modifier

Block’s zijn bedoeld om componenten herhaalbaar en simpel te maken. Zo kun je een block gebruiken op meerdere plekken zonder de code of de style aan te passen. Soms is het nodig om de styling van een specifiek block aan te passen. Je zou dan een “modifier” kunnen gebruiken. Modifiers worden gebruikt om het design aan te passen van een block. Het is dus geen ander block, maar hetzelfde block maar dan met een aanpassing aan het design. Dit benoem je door middel van de block naam gevolgd door de modifier met twee liggende streepjes (–) als prefix. Een prijs kan bijvoorbeeld verschillende modifiers hebben. Je hebt bijvoorbeeld de kortingsprijs (special price) en de oude prijs. Je zou bijvoorbeeld ook prijs inclusief of exclusief BTW hebben. Dit zijn allemaal modifiers van het price block. Ze hebben overigens allemaal dezelfde elementen en type eigenschappen maar dan met een ander design.

.price--special {}
.price--old {}
<span class=”price price--special”>
<span class=”price__currency”>€</span>
<span class=”price__value”>8,00</span>
</span>
<span class=”price price--old”>
<span class=”price__currency”>€</span>
<span class=”price__value”>10,00</span>
</span>

Andere voorbeelden van veelgebruikte modifiers zijn bijvoorbeeld in buttons. Je hebt bijvoorbeeld heel veel verschillende buttons. Dit zijn geen aparte block’s omdat ze allemaal dezelfde eigenschappen hebben maar met een ander jasje. Bijvoorbeeld de btn–primary, btn–secondary, btn–info, btn–warning etc. Een ander voorbeeld van een modifier dat vaak bij theming (ontwikkelen van diverse thema’s) gebruikt wordt is bijvoorbeeld zodra je een bepaalde event of actie hebt, of bijvoorbeeld een ander design voor een feestdag. Een kerstmis header zou je bijvoorbeeld kunnen benoemen met header–christmas.

Single Responsibility & DRY

Net zoals object-georiënteerd programmeren zal iedere CSS implementatie in de BEM methodologie zijn eigen verantwoordelijkheid hebben zoals het “Single Responsibility” principe. Dit betekent dat elk block een losstaand component is en overal los gebruikt kan worden zonder zijn style te verliezen. Het block kan dus onafhankelijk gebruikt worden. Het block is dus een herhaalbaar component en kun je dus op meerdere plekken gebruiken zonder de code aan te passen. Dit is ook wel het DRY principe ofwel Don’t Repeat Yourself.

Stel je hebt een prijscomponent. Dit bestaat uit een valuta en een waarde. Met de BEM methodologie kun je de style van dit component op een plek bijhouden. Het prijscomponent kun je op diverse plekken inzetten zonder zijn style te verliezen.

De style van het prijscomponent bestaat uit het lettertype, de grootte van het lettertype en de kleur. Dit zijn specifieke eigenschappen van het prijscomponent en vertelt nog niets over de positie of de padding en margin van het component. Dat zijn meer eigenschappen die we in een ander component kunnen plaatsen, bijvoorbeeld het price box component. Het price box component is een ander onafhankelijk component dat andere eigenschappen heeft zoals padding, achtergrondkleur en rand.

Waarom zouden we hier niet één component van maken? Het prijscomponent zou je in een price box component kunnen plaatsen bijvoorbeeld op een catalogus pagina terwijl je het prijscomponent ook wil gebruiken zonder het price box component, bijvoorbeeld in de winkelwagen in de header. De kracht van BEM is dat alle componenten compleet onafhankelijk van elkaar gebruikt kunnen worden.

.price-box {
padding: 20px;
background-color: #fefefe;
border: 1px solid #000;
border-radius: 3px;
}
.price-box__price {
display: inline-block;
}
.price {
font-family: Arial, sans-serif;
font-size: 1.6rem;
color: #000;
}
.price--old {
color: #ccc;
font-size: 1.2rem;
text-decoration: line-through;
}
<div class=”price-box”>
<div class=”price-box__price”>
<span class=”price price--special price-box__price--primary”>
<span class=”price__currency”>€</span>
<span class=”price__value”>8,00</span>
</span>
</div>
<div class=”price-box__price price-box__price--secondary”>
<span class=”price price--old”>
<span class=”price__currency”>€</span>
<span class=”price__value”>10,00</span>
</span>
</div>
</div>

Combinaties

Een veel gemaakte fout door ontwikkelaars is het gebruiken van elementen in elementen in naamgeving zoals .header__title__subtitle. Dit is een foutieve benaming doordat elementen geen onderliggende elementen kunnen hebben. Dit soort complicaties zou je creatief kunnen oplossen op diverse manieren. Wat ik heel vaak gebruik is elementen plaatsen binnen een element van een block. Echter is de subtitel wel een element van het header block. Ik zou hem ook kunnen gebruiken buiten de header__title, zonder de stijl te verliezen.

.header {}
.header__title {}
.header__title-subtitle {}
<div class=”header”>
<span class=”header__title”>
<span class=”header__title-subtitle”></span>
</span>
</div>

Een andere combinatie zou kunnen zijn dat je van een titel ook een block maakt. Een element van het titel block zou dan de subtitel kunnen zijn.

.header {}
.header__title {}
.title {}
.title__subtitle {}
<div class=”header”>
<div class=”header__title”>
<span class=”title”>
<span class=”title__subtitle”></span>
</span>
</div>
</div>

Je zou dit ook op een korte manier kunnen combineren in de HTML structuur. Dit is wel afhankelijk van of de styling dan zou breken, ja of nee. Als dit goed gaat zul je de styling niet moeten breken. Je zou bijvoorbeeld de header__title kunnen gebruiken voor de positionering binnen de header terwijl je de title gebruikt voor eigenschappen zoals lettertype, grootte van het lettertype en de kleur.

<div class=”header”>
<span class=”header__title title”>
<span class=”title__subtitle”></span>
</span>
</div>

Conclusie

BEM is een vaak gebruikte front-end methodologie voor de benaming van HTML en CSS elementen. BEM zorgt voor structuur en overzicht in de code en bevordert de kwaliteit en consistentie. Een block is een basis component dat onafhankelijk is van andere componenten. Elementen zijn onderdeel van het block. Modifiers worden gebruikt om het design aan te passen van het block.

Sinds dat ik het zelf toepas in mijn code merk ik dat mijn CSS en HTML een stuk gestructureerder en overzichtelijker is. Je kunt de CSS beter indelen en stukken code kun je makkelijker terugvinden. Toen we CSS nog in spaghetti code (alles door en onder elkaar zonder overzicht) schreven was het aanpassen van styling ongestructureerd en moeilijk te vinden. Vooral als je dan in de code van een ander iets moest aanpassen. Met BEM kunnen we dat voorkomen en is het leesbaar voor iedereen.

De BEM methodologie is zelf al een krachtige manier van CSS en HTML schrijven en structureren. In combinatie met Less en ITCSS is de BEM methodologie nog krachtiger. Less is een CSS pre-processor, waarmee je CSS kunt genereren door het gebruik van variabelen, mixins, functies en andere tools. ITCSS (Inverted Triangle CSS) is een manier om je CSS bestanden te organiseren en te structureren op basis van verschillende lagen. Dit zal ik een andere keer in een ander blogartikel toelichten.

Neem contact op

Neem contact met me op door te mailen naar info@ezrabotter.com of vul het contactformulier in.

Contact
Volg mij op

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd met *

2 × 4 =

Kop koffie?

Neem contact met me op door te mailen naar info@ezrabotter.com of vul het contactformulier in.

Neem contact op
Kopje koffie?