Blog overzicht

Veelgestelde vragen over BEM (CSS)

Ben jij naar aanleiding van onze vorige blogpost ook geprikkeld om te starten met de BEM-methode voor CSS? Misschien ben je zelfs al tegen bepaalde problemen of onbeantwoorde vragen aangelopen. In deze vervolgpost helpen we je graag verder om BEM beter te beheersen door acht prangende vragen te beantwoorden.

Is class=”block__element__element--modifier” mogelijk?

Het is niet de bedoeling dat je een element gaat nestelen binnen een ander element. Net zoals een block onafhankelijk en vrij verplaatsbaar is ten opzichte van andere blocks, is dit ook de bedoeling met elementen. Door elementen te nestelen, verlies je de vrijheid om de interne structuur van een block te veranderen. Wat als je besluit om het onderstaande element ‘product-list__list-item__product-header’ te verhuizen naar het element 'product-list__description'? Het gedeelte genaamd ‘list-item’ is in dat geval niet meer zo toepasselijk binnen de nieuwe structuur.

Dat je BEM-classes niet mag nestelen, betekent niet dat je HTML-tags ook niet mag nestelen. Anders zou je bijvoorbeeld onmogelijk een lijst kunnen maken. Een li-tag hoort nou eenmaal altijd binnen een ul- of ol-tag thuis.

 
Schrijfwijze elementHTML
Fout
<ul class=”product-list”>
<li class=”product-list__list-item”>
<div class=”product-list__list-item__product-header”>
Dit is de titel van het product.
</div>
<div class=”product-list__description>
Dit is de uitleg van het product.
</div>
</li>
</ul>
Goed
<ul class=”product-list”>
<li class=”product-list__list-item”>
<div class=”product-list__header”>
Dit is de titel van het product.
</div>
<div class=”product-list__description>
Dit is de uitleg van het product.
</div>
</li>
</ul>

Is class=”block block__element block__element--modifier” mogelijk?

Bij het benoemen van een modifier schrijf je altijd het bijhorende element of block ervoor. Dit is nodig omdat een modifier slechts aanvullende informatie bevat en de overige informatie in het block of element zelf staat.

De CSS-regels van het block/element en de modifier vormen dus gezamenlijk de gewenste stijl.

 
Schrijfwijze modifierHTML
Fout
<ul class=”product-list--aanbieding”>
<li class=”product-list__list-item--aanbieding”>
Aanbieding alleen vandaag geldig!
</li>
</ul>
Goed
<ul class=”product-list product-list--aanbieding”>
<li class=”product-list__list-item product-list__list-item--aanbieding”>
Aanbieding alleen vandaag geldig!
</li>
</ul>

Bij het benoemen van een element is dit anders. Een element bevat andere informatie dan een block en daarom zal je in een class nooit een block en element samen mogen noemen. Class=”product-list product-list__list-item” is dus niet mogelijk, enkel class=”product-list__list-item”.

Een element kan overigens wel samen met een block genoemd worden als het gaat om een losstaand block wat niet bij het element hoort (zie BEM-mix hierna). Class=”text product-list__list-item” is dus wel mogelijk.

Wanneer gaat een modificatie te ver?

Een modificatie bevat enkele wijzigingen op een bestaand block of element. Wanneer je het idee hebt dat je alle kenmerken van een block of element aan het aanpassen bent, is het beter om een nieuw block of element te maken.

 
Stijl modifierCSS
Fout
.card {
color: white;
font-weight: bold;
font-family: serif;
background-color: navy;
padding: 5px;
margin: 10px;
}

.card--aanbieding {
color: black;
font-weight: normal;
font-family: sans-serif;
background-color: white;
padding: 10px;
}
Goed
.card {
color: white;
font-weight: bold;
font-family: serif;
background-color: navy;
padding: 5px;
margin: 10px;
}

.card--aanbieding {
color: yellow;
border: 2px solid yellow;
}

Moet je echt alle HTML-tags een class geven?

Om een platte structuur te creëren, is het aan te raden om in beginsel alle HTML-tags (die je wilt stijlen) een class te geven. Dit lijkt in het begin veel werk, maar scheelt je later zorgen over specificiteit. Een niet-geclassificeerde HTML-tag heeft namelijk een lagere specificiteitswaarde dan een class.

Een mogelijke uitzondering op deze regel is een CSS-reset. Als je een anchor-tag eenmalig wilt stijlen om zo consistentie over verschillende browsers te behouden, hoef je deze reset niet per se met de BEM-methode op te lossen. De volgende code is voldoende:

a {
text-decoration: none;
}

Deze manier wordt overigens niet door iedereen omarmd. Een block die een anchor-tag gebruikt, is dan namelijk afhankelijk van een CSS-reset die geen onderdeel uitmaakt van het block zelf. Dit gaat in tegen de gedachte dat een block volledig onafhankelijk is van andere entiteiten. Je zou daarom in elk block dat een anchor-tag gebruikt een aparte CSS-reset moeten schrijven. Alhoewel dit misschien beter past in het BEM-verhaal, zorgt het voor veel gedupliceerde code.

De tweede uitzondering zijn componenten of systemen van derden die automatisch HTML-code genereren. Denk hierbij aan plug-ins voor Wordpress, die code genereren waar je zelf geen invloed op hebt.

Element of toch een nieuw block?

Als een entiteit fundamenteel onderdeel uitmaakt van een groter geheel, dan is het verstandig om er een element van te maken. Een li-tag zal vrijwel altijd een element zijn omdat het onderdeel is van een ul-tag. Aan de andere kant kan je een button-tag in veel scenario’s zelfstandig inzetten: in een header, formulier of pop-up bijvoorbeeld. Een button is daarom uitstekend als block aan te merken.

Pieker niet te veel over het verschil, want later is het alsnog mogelijk om van een element een apart block te maken. Classificeer in dat geval elke HTML-tag die je later schrijft als block in plaats van het oude element. Laat de oude code wel staan in je stylesheet om te voorkomen dat oude elementen hun stijl verliezen. Vergeet ook niet bij stijlwijzigingen het element mee te nemen door middel van een komma.

.oud-block__element, .nieuw-block {
margin: 10px;
}

Kan ik BEM combineren met een HTML-, CSS- en Javascript-framework?

Frameworks als Bootstrap of Foundation maken gebruik van hun eigen HTML-code en kennen geen BEM. Dit weerhoudt je er niet van om naast de code die deze frameworks genereren, je eigen code wel met behulp van de BEM-methode te schrijven. Je krijgt zo een mengeling van twee stijlen, wat niet per se nadelig is. De code van een framework is op deze manier erg snel te onderscheiden van je eigen code.

Kijk wel uit dat je geen namen voor blocks gebruikt die al bezet zijn door het framework. Bootstrap gebruikt voor zijn buttons bijvoorbeeld de class ‘btn’. Het is dan niet de bedoeling dat jij een block maakt met dezelfde class. Eén class zou dan twee stijlen dragen.

Is pop-up--red-border een goede naam voor een waarschuwingsmodifier?

In BEM bepaal je zelf hoe je blocks, elementen en modifiers noemt. Het is dan ook voorstelbaar dat je een modifier een naam geeft die gelijkstaat aan hetgeen wat het doet. Een modifier die zorgt voor een rode rand krijgt hierdoor de naam pop-up--red-border. Dit lijkt erg op de aanpak die in Atomic CSS gebruikt wordt en is voor de BEM-methode geen verstandige werkwijze.

Ten eerste kan het voorkomen dat je later besluit om de rode rand te wijzigen naar een gele rand. Een modifier met de naam pop-up--red-border is in dat geval niet meer toepasselijk of logisch.

Ten tweede hebben sommige modifiers meer dan één eigenschap. Wat als naast de rand ook de achtergrond een rode kleur moet krijgen en de tekst dikker moet zijn? Een modifier genaamd pop-up--red-border-red-backgroundcolor-white-text is gewoonweg niet praktisch.

Een semantische naamgeving die het achterliggende doel van de modifier beschrijft is daarom een betere oplossing. De modifier is bedoeld om van een normale pop-up een waarschuwingspop-up te maken. Een modifier met de naam pop-up--warning is voor deze situatie daarom uitstekend geschikt.

Is het mogelijk om een block te gebruiken binnen een ander block?

BEM is bedoeld om losse entiteiten te hergebruiken op meerdere posities. Een block gebruiken binnen een ander block is dus zeker een optie:

<form class=”contact-form”>
<button class=”button”>
</button>
</form>
Vragen rijzen als het button block een aangepaste vorm moet krijgen wanneer het zich bevindt binnen een contact-form block. Een manier om dit op te lossen is door gebruik te maken van een BEM-mix:
<form class=”contact-form”>
<button class=”button contact-form__button”>
</button>
</form>

Het button block heeft in dit geval de basiseigenschappen van een standaardknop, terwijl het element contact-form__button de extra eigenschappen draagt van een knop die zich binnen een contact-form bevindt.

Spelen met BEM-mixes kan erg verwarrend zijn omdat je rekening moet houden met het ‘single responsibility principle’, ‘open/closed principle’ en ‘external geometry and positioning’.

Een makkelijkere oplossing is om geen mixes te gebruiken maar voor het button block een nieuwe modifier te maken. 

<header class=”header”>
<button class=”button button--large”>
</button>
</header>

Het zij zo dat deze modifier misschien maar eenmaal gebruikt gaat worden. Je hebt in ieder geval de zorgen niet die je met BEM-mixes mogelijk wel krijgt.


We hopen je met deze 8 antwoorden weer een stap verder te hebben geholpen in je BEM-avontuur. Loop jij verder nog vast op onbeantwoorde vragen bij het gebruiken van de BEM-methode? Laat het ons weten in de commentaren hieronder.


Beoordeel dit artikel

Deel dit artikel

Gerelateerde artikelen

    • Leestijd: 8 minuten

Blog overzicht

Auteur: Akif Hodzic

Voorziet als contentmarketeer het blog van bruisende artikelen voor doorgewinterde techies en digitale nomaden om iedereen wegwijs te maken in de online wereld. Is daarnaast altijd te poken voor een potje Overwatch of een praatje over de laatste tv-series en tech-gadgets.