Подтвердить что ты не робот

Блок BEM, именование и вложенность

Я пытаюсь склонить голову вокруг соглашения об именах BEM. Я застрял в этом. Я могу что-то недопонимать, давайте посмотрим.

У меня есть навигатор боковой панели и контент nav.

Моя боковая панель выглядит так:

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

И мой контент nav выглядит так:

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

Теперь я столкнусь с проблемой, если я использую стиль .nav__item, они встречаются как в моих навигациях, так и не должны иметь одинаковый стиль. Должен ли я делать некоторые вложения здесь, или я неправильно назову свои блоки и элементы?

Пример вложения в CSS:

.content__nav .nav__item { background: Red; }

Или я должен назвать это следующим образом:

<li class="content__nav__item"><a href="#" class="content__nav__link">LINK</a></li>

Вы можете помочь?

4b9b3361

Ответ 1

Существует несколько вариантов написания классов BEM, поэтому имейте в виду, что это несколько конкурирующих стандартов. Это началось как набор правил. После публикации ответа Яндекс значительно пересмотрел свой официальный стандарт (это довольно улучшилось). Версия BEM я используется в основном из статьи Николаса Галлахера.

В этот момент я использую "Atomic OOBEMITLESS" , что на самом деле является просто способом сказать, что классы являются модульными и именными, селектора имеют низкую специфичность, и состояния могут быть переключенным с классами, которые позволяют масштабировать CSS, поверх препроцессора CSS, чтобы сделать код более кратким и выразительным.

Все, что сказал, я буду использовать следующий стандарт BEM:

  • имена дефисных классов в виде блоков:
    foo-bar
  • имя блока, за которым следует __, за которым следует дефинированное имя класса для элементов:
    foo-bar__fizz-buzz
  • имена блоков или элементов, за которыми следует --, за которыми следуют дефисные имена классов для модификаторов:
    foo-bar--baz, foo-bar--baz__fizz-buzz, foo-bar__fizz-buzz--qux

Краткая форма BEM: block-name__element-name--modifier-name


В ваших примерах есть три разных блока:

  • sidebar, который имеет элемент sidebar__nav
  • content, который имеет элемент content__nav
  • nav, который имеет элементы nav__item и nav__link

Блоки sidebar и content выглядят вариациями одного и того же блока и могут быть представлены как .region.region--sidebar и .region.region--content.

Блок nav неявна в элементе ul, и вы должны сделать его явным:

<ul class="nav"><!-- could be content__nav or sidebar__nav as well if you choose -->
    <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>

Как только вы указали, что элемент ul является блоком nav, имеет смысл модифицировать блок nav:

<ul class="nav nav--content">
    <li class="nav__item nav--content__item"><a href="#" class="nav__link nav--content__link">LINK</a></li>
    <li class="nav__item nav--content__item"><a href="#" class="nav__link nav--content__link">LINK</a></li>
</ul>

После того, как вы настроили классы CSS, стилизация всех элементов nav__item проста:

.nav__item {
    ...styles here...
}

и переопределение этих стилей для элементов контента nav__item:

.nav--content__item {
    ...styles here...
}

Ответ 2

Вероятно, вам стоит взглянуть на часто задаваемые вопросы BEM.

Каким будет имя класса для элемента внутри другого элемента? .block__elem1__elem2?

Что делать, если мой блок имеет сложную структуру и его элементы вложены? Классы CSS, такие как block__elem1__elem2__elem3, выглядят пугающими. Согласно методу BEM блочная структура должна быть сглажена; вам не нужно отображать вложенную структуру DOM блока. Итак, имена классов для этого случая:

.block{}
.block__elem1{}
.block__elem2{}
.block__elem3{}

В то время как представление DOM блока может быть вложенным:

<div class='block'>
    <div class='block__elem1'>
        <div class='block__elem2'>
            <div class='block__elem3'></div>
        </div>
    </div>
</div>

Помимо того, что классы выглядят намного приятнее, он заставляет элементы зависеть только от блока. Таким образом, вы можете легко перемещать их по блоку при внесении изменений в интерфейс. Изменениям структуры DOM блока не нужны соответствующие изменения в CSS-коде.

<div class='block'>
    <div class='block__elem1'>
        <div class='block__elem2'></div>
    </div>
    <div class='block__elem3'></div>
</div>

Ответ 3

Рассмотрим идею пар _key_value для модификаторов (блок или элемент отделен от имени модификатора одним подчеркиванием и его значением с другим).

Имеет смысл различать модификаторы один от другого (например, nav_type_content и nav_type_sidebar - это то место, где nav apper на странице, но модификация темы, размера или создания ссылок через ajax различна) и поэтому, чтобы понять, какие модификаторы не могут использоваться вместе на одном DOM- node.

Также удобнее работать с парами ключ: значение в javascript.

И есть довольно много готовых компонентов и инструментов, которые используют такое соглашение: https://github.com/bem/