Именование подблоков BEM

Я использую подход BEM для написания html + css. С помощью этого синтаксиса:

  • Блоки: имя_блока
    • Элементы: block_name__element_name
    • Модификаторы: block_name__element_name - модификатор

Я запутался, когда у меня есть блок внутри другого блока. Например, в заголовке я хочу, чтобы заголовок был блоком, который я могу ссылаться, а nav и логотип - блоки. Я хочу ссылаться на эти блоки nav и logo как на сайт site_header. Но как бы я это написал? Цепочки блоков, такие как block_name__sub_block_name, выглядят довольно долго.

Есть ли у кого-нибудь типичный способ написать этот пример?

<div class="site_header__logo">
    <a class="site_header__logo__link">
        <img class="site_header__logo__image">
    </a>
</div>

<nav class="site_header__main_nav">
    <ul>
        <li class="site_header__main_nav__item">
            <a class="site_header__main_nav__link">Home</a>
        </li>
        <li class="site_header__main_nav__item">
            <a class="site_header__main_nav__link">About Us</a>
        </li>
        <li class="site_header__main_nav__item">
            <a class="site_header__main_nav__link">Contact Us</a>
        </li>
    </ul>
</nav>

<div class="site_header__phone">
    <p class="site_header__phone__number">
        555.555.5555
    </p>
</div>

Ответ 1

Я думаю, что логотип, главный заголовок и телефон соответствуют определению block, которое дается на веб-сайте BEM:

Блок - это независимый объект, "строительный блок" приложения. Блок может быть простым или составным (содержащим другие блоки).

У вас есть три простых блока (логотип, main_nav и телефон) в составном блоке (site_header). Он действительно очень похож на составной блок HEAD, который приведен в качестве примера на странице методологии методологии BEM.

Поэтому я бы написал это так:

<div class="logo">
    <a class="logo__link">
        <img class="logo__image">
    </a>
</div>

<nav class="main_nav">
    <ul>
        <li class="main_nav__item">
            <a class="main_nav__link">Home</a>
        </li>
        <li class="main_nav__item">
            <a class="main_nav__link">About Us</a>
        </li>
        <li class="main_nav__item">
            <a class="main_nav__link">Contact Us</a>
        </li>
    </ul>
</nav>

<div class="phone">
    <p class="phone__number">
        555.555.5555
    </p>
</div>

Если вы считаете, что "логотип" слишком обобщен как имя и не будет представлять другие типы логотипов в проекте, не стесняйтесь дать ему другое имя, например "company_logo".

С точки зрения стиля, BEM предлагает использовать модификаторы блоков и модификаторы элементов для представления их разных стилей. Например, если вы хотите, чтобы ваш номер телефона выделен жирным шрифтом, вы можете создать модификатор класса для него в CSS и применить его к своему HTML следующим образом:

.phone__number--bold {
    font-weight: bold;
}

<div class="phone">
    <p class="phone__number phone__number--bold">
        555.555.5555
    </p>
</div>

Модификаторы являются предпочтительным способом для блоков стилизации в других блоках. Поэтому не делать это:

.site_header .phone__number {
    font-weight: bold;
}

Я думаю, что есть одно исключение из этого, когда вы хотите дать "зависимые от местоположения стили" внутри блока. Скажем, что вы хотите дать левую границу блоку "логотип". Вместо создания модификатора типа:

.logo--push_20 {
    margin-left: 20px;
}

лучше следовать второму принципу OOCSS - Разделить контейнер и содержимое - и оставить задание в контейнере:

.site_header .logo {
    margin-left: 20px;
}

Ответ 2

Вы также можете посмотреть FAQ 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

Да, вы можете вырезать много в именах классов. Например:

HTML:

`

<nav class="site_header">
    <ul>
        <li class="nav_item">
            <a class="nav_link">Home</a>
        </li>
        <li class="nav_item">
            <a class="nav_link">About Us</a>
        </li>
        <li class="nav_item">
            <a class="nav_link">Contact Us</a>
        </li>
    </ul>
</nav>

`

Затем в ваш CSS помещаем:

`

.site_header { 
    ... stuff ...
}

.site_header .nav_item {
    ... nav_item stuff ...
}

.site_header .nav_link {
    ... nav_link stuff ...
}

`