最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - BEM and "active" classesDecoupling HTML and JS - Stack Overflow

programmeradmin1浏览0评论

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 and nav__list. Applying nav to the ul would be better. Also I don't think nav__link and nav__item provide much help, because our navigations are a list anyway. Using nav > 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 a li or a span, what so ever and but tells you exactly what's going on. Sure, it suggest there eventually is a nav__item as well and there is, but not as a assigned class. Edit: Also I was talking about a nav-class for ul's, not the nav-tag. – kleinfreund Commented Jan 1, 2014 at 20:53
  • 1 Seeing it this way the ul would be the abstraction of the navigational concept and nav the wrapper used for styling: <nav class=site-navigation role=navigation>. You could also use something like site-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 uses nav and li, div and a, div and div and so on. That's why nav__item and nav__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
 |  Show 3 more ments

2 Answers 2

Reset to default 6

BEM 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.

发布评论

评论列表(0)

  1. 暂无评论