As people are still advising to use BEM for larger projects I thought I might give it a shot. But I already run into a problem by setting up the header
-element of the page.
This is how the page's header looks now:
<header class="header">
<img class="header__logo" src="logo.png" alt="alt">
<button class="header__button-toggle" type="button">Open menu</button>
<nav class="header__nav" role="navigation">
<ul>
<li><a href="">Nav item A</a></li>
<li><a href="">Nav item B</a></li>
<li><a href="">Nav item C</a></li>
</ul>
</nav>
</header>
I understand how to define simple elements, like header__logo
or header__button-toggle
.
However I'm not sure what to do, when it comes to the nav
-element. The HTML is not going to change, as this is a common and well approved pattern and will be the same in 5 years, I guess.
Now I need to apply styles not only to the nav
-element but also to the ul
, the li
and the a
-elements as well. How do I do this?
I would do it like this in Less:
.header {
&__nav {
property: value;
ul { property: value; }
li { property: value; }
a { property: value; }
}
}
But is this valid in BEM or is this what BEM wants to eliminate?
Must I end up with something like this instead?
.header {
&__nav {
property: value;
&__list { property: value; }
&__item { property: value; }
&__anchor { property: value; }
}
}
Which clutters the HTML extremely:
<nav class="header__nav" role="navigation">
<ul class="header__nav__list">
<li class="header__nav__item">
<a class="header__nav__anchor" href="">Nav item A</a>
</li>
<li class="header__nav__item">
<a class="header__nav__anchor" href="">Nav item B</a>
</li>
<li class="header__nav__item">
<a class="header__nav__anchor" href="">Nav item C</a>
</li>
</ul>
</nav>
Maybe someine can help me understand, how this would be solved correctly in terms of BEM.
Yes, you should assign a class to each element you need to address in CSS (see: https://en.bem.info/methodology/html/#binding-blocks-to-a-dom-node). And you should not be afraid of extra bytes in your markup as gzip will compress it just fine.
But you should avoid elements of the elements (please refer to: https://en.bem.info/methodology/faq/#can-i-create-elements-of-elements-block__elem1__elem2 for reasoning).
So proper markup will be like this:
<nav class="header__nav nav" role="navigation">
<ul class="nav__list">
<li class="nav__item">
<a class="nav__anchor" href="">Nav item A</a>
</li>
<li class="nav__item">
<a class="nav__anchor" href="">Nav item B</a>
</li>
<li class="nav__item">
<a class="nav__anchor" href="">Nav item C</a>
</li>
</ul>
</nav>
You may also noticed that there are two different classes on nav
element. That's called mix
in BEM methodology: https://en.bem.info/methodology/css/#mixes