Правила БЭМ в HTML и CSS
Имена классов — половина БЭМ. Вторая половина — правила для самих селекторов. Они и дают главную выгоду: стили любого блока можно читать, менять и удалять, не боясь задеть остальную страницу.
Только классы
В CSS по БЭМ селекторы состоят из классов. Селекторы тегов и id для оформления компонентов не используют:
| Нельзя | Можно | Почему |
|---|---|---|
h3 | .card__title | тег <h3> есть на всей странице |
#cart | .cart | id очень сильный, и он один на странице |
.card h3 | .card__title | заголовок поменяют на <h2> — стиль пропадёт |
Класс не зависит от того, какой тег выбран. Заголовок карточки можно сделать <h2> или <p> ради семантики, и вид не изменится. Исключение — базовые стили сайта вроде сброса и body, о них говорилось в уроке «Как организовать CSS».
Плоская специфичность
Почти каждый селектор — один класс. У всех правил одинаковая сила, поэтому побеждает то, что ниже, и ничего не нужно «перебивать»:
<style>
.note { padding: 8px 12px; border-left: 4px solid royalblue; background: aliceblue; }
.note__text { margin: 0; }
.note--warning { border-left-color: orange; background: oldlace; }
</style>
<div class="note"><p class="note__text">Обычная заметка</p></div>
<div class="note note--warning"><p class="note__text">Внимание: склад закрыт в воскресенье</p></div>Модификатор стоит ниже блока и побеждает, хотя у селекторов одинаковая специфичность. Это и есть плоская специфичность.
Допустимые исключения
Есть два случая, когда селектор из двух частей оправдан. Первый — псевдоклассы и состояния: .button:hover, .input:focus. Второй — модификатор блока, который меняет его элементы:
<style>
.card { padding: 12px; border: 1px solid silver; border-radius: 8px; max-width: 200px; margin-bottom: 8px; }
.card__price { color: seagreen; font-weight: bold; }
.card--sale .card__price { color: crimson; }
</style>
<div class="card">Рюкзак <span class="card__price">40 €</span></div>
<div class="card card--sale">Палатка <span class="card__price">72 €</span></div>Один модификатор на блоке перекрасил цену внутри, и не пришлось ставить модификатор на каждый элемент.
Файлы по блокам
В большом проекте стили каждого блока лежат в своей папке. Рядом можно хранить и его картинки, и скрипт:
blocks/
button/
button.css
card/
card.css
card__price.css (по желанию — отдельный файл для элемента)
header/
header.css
styles.css @import всех блоков по очередиУдалили блок — удалили папку, и вместе с ней исчезли все его стили. Мёртвому CSS просто негде остаться.
Частая ошибка
Оформлять теги внутри блока вместо элементов:
<style>
.card { padding: 12px; border: 1px solid silver; border-radius: 8px; max-width: 240px; }
.card p { margin: 0 0 8px; color: gray; }
.notice { padding: 8px; background: gold; }
.notice__text { margin: 0; color: black; font-weight: bold; }
</style>
<div class="card">
<p>Описание товара</p>
<div class="notice"><p class="notice__text">Осталось 2 штуки!</p></div>
</div>Правило .card p задело абзац вложенного блока notice: текст стал серым, хотя у него есть свой класс, — .card p сильнее одного класса. Дайте абзацу карточки собственный класс card__text, и правило перестанет попадать в чужие теги.