I am trying to wrap my head around BEM naming convention. I am stuck at this. I may misunderstanding something, lets see.
I have a sidebar nav and a content nav.
My sidebar nav looks like this
<div class="sidebar">
<ul class="sidebar__nav">
<li class="nav__item"><a href="#" class="nav__link">LINK</a></li>
<li class="nav__item"><a href="#" class="nav__link">LINK</a></li>
</ul>
</div>
And my content nav looks like this
<div class="content">
<ul class="content__nav">
<li class="nav__item"><a href="#" class="nav__link">LINK</a></li>
<li class="nav__item"><a href="#" class="nav__link">LINK</a></li>
</ul>
</div>
Now I will run into a problem if I style .nav__item, they occur in both my navigations and should not have the same styling. Should I do some nesting here, or am I naming my blocks and elements wrong?
Nesting example in CSS:
.content__nav .nav__item { background: Red; }
Or should I name it like this:
<li class="content__nav__item"><a href="#" class="content__nav__link">LINK</a></li>
Can you help?
There are a number of variants on how to write BEM classes, so be aware that are multiple competing standards. It started as a set of loose guidelines. Since posting this answer, Yandex has significantly overhauled their official standard (it's quite an improvement). The version of BEM I use is based heavily from an article by Nicolas Gallagher.
At this point I use "Atomic OOBEMITLESS", which is really just a way of saying that classes are modular and namespaced, selectors have low specificity, and states may be toggled with classes which allows CSS to be scaled, on top of a CSS preprocessor to make the code more concise and expressive.
All that said, I will be using the following BEM standard:
foo-bar
__
followed by hyphenated class names for elements:foo-bar__fizz-buzz
--
followed by hyphenated class names for modifiers:foo-bar--baz
,foo-bar--baz__fizz-buzz
,foo-bar__fizz-buzz--qux
BEM short form:
block-name__element-name--modifier-name
You have three different blocks in your examples:
sidebar
, which has asidebar__nav
elementcontent
, which has acontent__nav
elementnav
, which hasnav__item
andnav__link
elementsThe
sidebar
andcontent
blocks appear to be variations on the same block, and could be represented as.region.region--sidebar
and.region.region--content
.The
nav
block is implicit on theul
element, and you should make it explicit:Once you've specified that the
ul
element is anav
block, it makes sense to have thenav
block be modified:Once you've set up the CSS classes, styling all
nav__item
elements is simply:and overriding those styles for the content
nav__item
elements is:Consider idea of
_key_value
pairs for modifiers (block or element is separated from modifier name with one underscore and its value with another one).That makes sense to distinguish modifiers one from another (e.g.
nav_type_content
andnav_type_sidebar
are both about the place wherenav
apper on the page but modifiers setting theme, size or making links work via ajax are different) and so to understand which modifiers can't be used together on one DOM-node.Also it's more convenient to work with key: value pairs in javascript.
And there are quite a lot of ready-made components and tools which uses such convention: https://github.com/bem/
You should probably have a look at BEM's FAQ.
Whereas the DOM representation of the block may be nested:
Besides the fact that the classes look much nicer, it makes the elements be dependent on the block only. So, you can easily move them across the block when providing changes to the interface. The changes of the block DOM structure would not need corresponding changes to the CSS code.