БЭМ и активные классы / Разделение HTML и JS

Я начал использовать методологию БЭМ, чтобы отделить свой HTML и CSS... и в большинстве случаев это работает очень хорошо. Даже если это только ваше личное мнение, я все равно хотел бы знать, как другие справляются с этим:

Предположим, нам нужно построить простую навигацию. HTML выглядит примерно так

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

Я не уверен, нужны ли мне ".nav_item" и ".nav_link" или лучше использовать их вместо этого

.nav__list > li { CODE }

Но моя настоящая проблема заключается в том, как работать с «активными» классами (не только для навигации, но и вообще). Лучше ли использовать определенные «активные» классы, такие как «.nav_item--active», чтобы вы могли просто использовать один класс внутри вашего файла CSS, или если работает использование более общих имен классов, таких как «.is-active». лучше? Но тогда вам нужно указать свои классы внутри файла CSS, например «.nav_item.is-active» или (что мне кажется еще хуже) «.nav__list > .is-active».

У каждого метода есть свои минусы. Для меня второй способ выглядит неправильным при использовании БЭМ, но если вы идете по первому пути, вы столкнетесь с «проблемами» с вашим JS, потому что вам нужно «жестко закодировать» конкретное имя класса в вашем JS.

someElement.addClass(".nav__item--active");

Таким образом, ваш JS слишком сильно зависит от вашей HTML-структуры (или это не имеет большого значения?), которая может измениться... И это приводит ко второму вопросу. Я слышал, что хорошо разделять не только HTML и CSS, но и HTML и JS. Таким образом, вы могли бы, например, использовать эти классы «.js-» для добавления событий кликов и всего подобного к элементам вместо того, чтобы использовать классы «стиля» для запуска таких событий. Поэтому вместо использования

<button class="btn btn--large"></button> // $(".btn--large") in jQuery

вам придется

<button class="btn btn--large js-dostuff"></button> // $(".js-dostuff") in jQuery

Я думаю, что это в сочетании с атрибутами данных HTML5 работает практически для всего, но я спрашиваю себя, что происходит с навигацией, аккордеонами или подобными вещами. Лучше ли для удобства обслуживания использовать эти классы ".js-" (для каждого элемента)

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

или я должен использовать $(".nav__item")... в моем JS в этом случае? Но таким образом вы на самом деле не разделяете свой HTML и JS (по крайней мере, насколько я понял эту тему). Речь идет не только о навигации, но и обо всех подобных взаимодействиях с javascript, таких как аккордеоны, ползунки и так далее.

Я надеюсь, что вы, ребята, поделитесь некоторыми рекомендациями по этим вопросам и поможете мне.

Спасибо


person Daniel    schedule 06.11.2013    source источник
comment
Разве не избыточно иметь и nav, и nav__list. Применение nav к ul было бы лучше. Также я не думаю, что nav__link и nav__item сильно помогают, потому что наша навигация в любом случае представляет собой список. Использование nav > li просто прекрасно.   -  person kleinfreund    schedule 01.01.2014
comment
@kleinfreund Спасибо, я думаю, вы правы, что nav__link и nav__item слишком много. Но если я не использую классы для ‹li›, я все еще не знаю, как назвать активные классы (поскольку nav__item--active больше не имеет смысла). И мне не очень нравятся неспецифические активные классы, такие как активные, потому что тогда мне нужно было бы иметь что-то вроде .nav › li.active › a в моем CSS, и все мои разные классы .active, вероятно, когда-нибудь перепутались бы.   -  person Daniel    schedule 01.01.2014
comment
Я не вижу большой проблемы в использовании nav__item--active. Это достаточно свободно, чтобы быть либо li, либо span, что угодно, но точно говорит вам, что происходит. Конечно, это предполагает, что в конечном итоге nav__item тоже есть, но не как назначенный класс. Редактировать: Также я говорил о nav-классе для ul, а не о nav-теге.   -  person kleinfreund    schedule 02.01.2014
comment
@kleinfreund Еще раз спасибо, теперь я понял вашу точку зрения. Я согласен, что специальные классы для ‹li› и ‹a› не очень помогают. Однако полностью просмотрел ваш комментарий к классу .nav для ul. Мне нужно подумать об этом, поскольку даже для ‹nav› нужен какой-то класс (на случай, если в будущем будет больше, чем один ‹nav›), и я не могу придумать ничего лучше, чем использовать .nav или . первичная навигация или что-то еще.   -  person Daniel    schedule 02.01.2014
comment
С этой точки зрения ul будет абстракцией навигационной концепции, а nav — оболочкой, используемой для стилизации: <nav class=site-navigation role=navigation>. Вы также можете использовать что-то вроде site-navigation--active, чтобы указать состояние только для этой навигации.   -  person kleinfreund    schedule 02.01.2014
comment
nav > li не очень OOCSS, потому что вы подразумеваете элементы, которые будут использоваться. CSS должен работать независимо от того, использует ли HTML nav и li, div и a, div и div и так далее. Поэтому nav__item и nav__link предпочтительнее.   -  person howard10    schedule 03.04.2014
comment
@kleinfreund Я не думаю, что nav__link и nav__item сильно помогают, потому что наша навигация в любом случае представляет собой список: как указал Howard10, основное преимущество этой техники заключается в том, что вы отделяете любой HTML-тег, который используете, от стиля. Упрощает поддержку и рефакторинг кода.   -  person Adrien Be    schedule 08.09.2014
comment
Я согласен с @ Howard10, то же самое верно и для заголовков. Например: .banner__h2 должно быть .banner__heading, так как структуры заголовков часто могут меняться, чтобы помочь структуре документа или некоторым преимуществам SEO.   -  person nickspiel    schedule 17.01.2015


Ответы (2)


Методология БЭМ говорит, что вы не должны использовать какие-либо глобальные селекторы, такие как селекторы тегов, поэтому используйте nav__item и nav__link.

Та же история с активным модификатором. У вас не должно быть никаких глобальных сущностей (вы можете использовать миксы, но это немного другое). Так что лучше всего использовать nav__item--active (или nav__item_state_active в классической нотации БЭМ).

А у БЭМ есть решение для JS, HTML (или шаблонов) и вообще для любой другой блочной технологии.

Основная идея в том, что блок знает о себе все: как он выглядит (css), как работает (js), какой html должен выдавать (шаблоны), свои тесты, документацию, изображения и т.д. .

А так как технология css навигационного блока применяет правила декларативным образом (вы определяете некоторый селектор, и все узлы, соответствующие этому селектору, оформляются в соответствии с этими правилами), так же вы можете описать js навигационного блока.

Пожалуйста, взгляните на http://xslc.org/jquery-bem/, который является плагином jquery, который дает вам возможность легко работать с блоками в БЭМ.

И если вы используете какую-то систему сборки, вы можете поместить все эти технологии в одну папку в файловой системе:

blocks/
    nav/
        __list/
            nav__list.css
            nav__list.js
        __item/
            nav__item.css
        nav.css
        nav.js
        nav.test.js
        nav.png
        nav.md

Имея такую ​​файловую структуру, вы можете углубиться в суть БЭМ и попробовать i-bem.js: http://bem.info/articles/bem-js-main-terms/

person tadatuta    schedule 07.11.2013
comment
Спасибо, это очень помогает! - person Daniel; 07.11.2013
comment
@tadatuta спасибо за ваш ответ, но я стараюсь свести к минимуму количество js-плагинов, которые я использую, и их зависимостей, кроме того, у плагина, на который вы ссылаетесь, есть только 2 участника и практически нет активности других пользователей, см. графики / билеты и другое темы, связанные с историей, на github.com/hoho/jquery-bem/graphs/contributors - person Adrien Be; 08.09.2014
comment
@AdrienBe да, но я думаю, что было бы вполне разумно написать несколько помощников для установки/получения/переключения/удаления модификаторов и использования их везде в вашем коде. - person tadatuta; 09.09.2014
comment
В этом ответе на самом деле не упоминается проблема вашего JS в зависимости от структуры HTML, которая закодирована в именах классов. Как с этим бороться? Существуют ли какие-либо инструменты, которые генерируют метаинформацию БЭМ для JS? - person Tomáš Zato - Reinstate Monica; 17.06.2019

На самом деле, js с точки зрения bem часто считают не такой уж хорошей идеей. Например, bem отлично подходит для локализации и перемещения отношений в css в горизонтальном масштабе, но с точки зрения js сложно абстрагировать логику в очень сложных приложениях.

В react.js вы можете использовать его для именования классов, и все (мы используем его таким образом, и он отлично работает!). Я написал библиотеку для устранения проблем с именами.

person Bloomca    schedule 18.10.2015