I've started using BEM methodology to decouple my HTML and CSS ... and it works pretty well most of the time. Even if its only your personal opinion, i would still like to know how others deal with this:
Let's assume we need to build a simple navigation. The HTML looks similar to
<nav class="nav">
<ul class="nav__list">
<li class="nav__item">
<a class="nav__link" href=""></a>
</li>
<li class="nav__item">
<a class="nav__link" href=""></a>
</li>
</ul>
</nav>
I'm not sure if i need the ".nav_item" and ".nav_link" or if it's better pratice to use this instead
.nav__list > li { CODE }
But my real issue is how to deal with "active" classes (not just for navigations, but in general). Is it better to use specific "active" classes like ".nav_item--active", so you can just use a single class inside your CSS file or if using more general class names like ".is-active" works better? But then you need to specify your classes inside your CSS file like ".nav_item.is-active" or (which looks even worse to me) ".nav__list > .is-active".
Every method has its downsides. To me the second way looks wrong if using BEM, but if you are going for the first way you run into "troubles" with your JS, because you need to "hard-code" the specific class name into your JS
someElement.addClass(".nav__item--active");
That way your JS relies too much on your HTML structure (or doesn't this matter too much?), which might change... And this leads to the second question. I heard that it's good to decouple not only your HTML and CSS but also your HTML and JS. So you could for example use those ".js-" classes to add click events and all that kind of stuff to elements instead of using your "styling" classes to trigger those kind of events. So instead of using
<button class="btn btn--large"></button> // $(".btn--large") in jQuery
you would have
<button class="btn btn--large js-dostuff"></button> // $(".js-dostuff") in jQuery
I think this in bination with HTML5 data-attributes works for pretty much for anything, but i'm asking myself what happens to navigation or accordions or stuff like that. Is it better for maintainability to use those ".js-" classes as well (for every item)
<nav class="nav">
<ul class="nav__list">
<li class="nav__item js-open-subnav">
<a class="nav__link" href=""></a>
<ul class="nav__sub">
<!-- ... -->
</ul>
</li>
</ul>
</nav>
or should i use $(".nav__item")... in my JS in this case? But that way you don't really decouple your HTML and JS (at least as far i understood this topic). It's not just about navigations, but about all those kind of javascript interactions, like accordions, sliders and so on.
I'll hope you guys can share some best practices for those questions and help me out.
Thanks
I've started using BEM methodology to decouple my HTML and CSS ... and it works pretty well most of the time. Even if its only your personal opinion, i would still like to know how others deal with this:
Let's assume we need to build a simple navigation. The HTML looks similar to
<nav class="nav">
<ul class="nav__list">
<li class="nav__item">
<a class="nav__link" href=""></a>
</li>
<li class="nav__item">
<a class="nav__link" href=""></a>
</li>
</ul>
</nav>
I'm not sure if i need the ".nav_item" and ".nav_link" or if it's better pratice to use this instead
.nav__list > li { CODE }
But my real issue is how to deal with "active" classes (not just for navigations, but in general). Is it better to use specific "active" classes like ".nav_item--active", so you can just use a single class inside your CSS file or if using more general class names like ".is-active" works better? But then you need to specify your classes inside your CSS file like ".nav_item.is-active" or (which looks even worse to me) ".nav__list > .is-active".
Every method has its downsides. To me the second way looks wrong if using BEM, but if you are going for the first way you run into "troubles" with your JS, because you need to "hard-code" the specific class name into your JS
someElement.addClass(".nav__item--active");
That way your JS relies too much on your HTML structure (or doesn't this matter too much?), which might change... And this leads to the second question. I heard that it's good to decouple not only your HTML and CSS but also your HTML and JS. So you could for example use those ".js-" classes to add click events and all that kind of stuff to elements instead of using your "styling" classes to trigger those kind of events. So instead of using
<button class="btn btn--large"></button> // $(".btn--large") in jQuery
you would have
<button class="btn btn--large js-dostuff"></button> // $(".js-dostuff") in jQuery
I think this in bination with HTML5 data-attributes works for pretty much for anything, but i'm asking myself what happens to navigation or accordions or stuff like that. Is it better for maintainability to use those ".js-" classes as well (for every item)
<nav class="nav">
<ul class="nav__list">
<li class="nav__item js-open-subnav">
<a class="nav__link" href=""></a>
<ul class="nav__sub">
<!-- ... -->
</ul>
</li>
</ul>
</nav>
or should i use $(".nav__item")... in my JS in this case? But that way you don't really decouple your HTML and JS (at least as far i understood this topic). It's not just about navigations, but about all those kind of javascript interactions, like accordions, sliders and so on.
I'll hope you guys can share some best practices for those questions and help me out.
Thanks
Share Improve this question edited Dec 6, 2013 at 9:33 mrksbnch asked Nov 6, 2013 at 23:57 mrksbnchmrksbnch 1,8423 gold badges29 silver badges48 bronze badges 8-
1
Isn't it redundant to have both
nav
andnav__list
. Applyingnav
to the ul would be better. Also I don't thinknav__link
andnav__item
provide much help, because our navigations are a list anyway. Usingnav > li
is just fine imo. – kleinfreund Commented Jan 1, 2014 at 15:21 -
1
I don't see a big problem in using
nav__item--active
. It's loose enough to bei either ali
or aspan
, what so ever and but tells you exactly what's going on. Sure, it suggest there eventually is anav__item
as well and there is, but not as a assigned class. Edit: Also I was talking about anav
-class for ul's, not thenav
-tag. – kleinfreund Commented Jan 1, 2014 at 20:53 -
1
Seeing it this way the
ul
would be the abstraction of the navigational concept andnav
the wrapper used for styling:<nav class=site-navigation role=navigation>
. You could also use something likesite-navigation--active
to indicate the state only for this navigation. – kleinfreund Commented Jan 2, 2014 at 9:33 -
4
nav > li
isn't very OOCSS because you're implying the elements that will be used. The CSS should work whether the HTML usesnav
andli
,div
anda
,div
anddiv
and so on. That's whynav__item
andnav__link
would be preferable. – howard10 Commented Apr 3, 2014 at 16:46 -
1
I agree with @howard10, the same would be true for headings. For example:
.banner__h2
should be.banner__heading
as heading structures can often change to aide the document outline or some SEO benefit. – nickspiel Commented Jan 16, 2015 at 23:11
2 Answers
Reset to default 6BEM methodology says you shouldn't use any global selectors such as tag selectors so use nav__item and nav__link.
The same story with active modifier. You shouldn't have any global entities (you can use mixes but that's a bit different thing). So the best way is to go with nav__item--active (or nav__item_state_active in classic BEM notation).
And BEM has sollution for JS, HTML (or templates) and actually any other block's technology.
The main idea is that block knows everything about itself: how it looks (css), how it works (js), what html it should produce (templates), its own tests, documentation, images, etc.
And as css technology of the nav block applies rules in declarative way (you define some selector and all the nodes which match this selector are styled with these rules) the same way you can describe js of the nav block.
Please take a look at http://xslc/jquery-bem/ which is jquery plugin which gives you possibility to work with blocks in BEM way easily.
And in case you use some build system you can put all these technologies in the same folder on filesystem:
blocks/
nav/
__list/
nav__list.css
nav__list.js
__item/
nav__item.css
nav.css
nav.js
nav.test.js
nav.png
nav.md
Having such file structure you may go deeper to what BEM actualy is and try i-bem.js: http://bem.info/articles/bem-js-main-terms/
Actually, js in terms of bem often considered as not such good idea. For instance, bem is great to localize and move relations in css to horizontal scale, but in terms of js it's hard to abstract logic in very plex applications.
In react.js you can use it for class naming, and that's it (we use it this way and it works fine!). I wrote a library for decoupling problem with naming.