Як працювати з CSS-препроцесорами та БЕМ
Список рекомендацій щодо неускладнення життя собі та іншим учасникам проекту з верстки.
Зміст
Sass, LESS, stylus, PostCSS.
Якщо у вас є що доповнити або ви хочете взяти участь у розробці цих угод, будь ласка, створіть issue на GitHub або форкніть репозиторій та надішліть pull request.
Золоті правила
Дотримуйтесь запропонованих тут або власних угод.
Є ситуації, коли правила треба порушити. Причина має бути справді серйозною, не ймовірною.
- Весь код проекту має виглядати так, ніби він написаний однією людиною, незалежно від кількості розробників.
- Робити потрібно настільки просто, наскільки це можливо. Але не простіше.
- Будь-який інструмент при бездумному використанні може вистрілити у ногу.
БЕМ (як спосіб іменування селекторів)
- Самодокументованість.
- Імітація простору імен (простота та безпека модифікації).
- Відсутність залежності від DOM структури.
- Проектне використання блоків.
- Кроспроектне використання блоків.
Саме поняття БЕМ - не тільки спосіб іменування селекторів, але парадигма сприйняття проекту як набору сутностей (блоки, елементи, модифікатори). Повний стек БЕМ має на увазі подвійну шаблонізацію та має відносно високий поріг входу. Використовуйте БЕМ хоча б як спосіб іменування селекторів.
Блок – це самостійна частина сторінки
- Назва класу має бути простою і короткою.
- Назва класу має відповідати питанням «Що це?»
- Не використовуйте скорочення крім найчастіших
- Назване повинна відповідати на запитання «Як виглядає?»
Блоки можна і потрібно вкладати один в одного
- Немає обмежень на вкладення блоків, крім здорового глузду.
- Жодної додаткової специфіки вкладені блоки не мають.
Елемент - частина БЕМ-блоку
- Назва класу формується із назви блоку з додаванням __ та назви елемента.
- Назва класу має бути простою і короткою.
- Назва класу має відповідати питанням «Що це?»
- Уникайте скорочень, крім найчастіших.
- Назване повинна відповідати на запитання «Як виглядає?»
Елемент можна використовувати поза його блоком лише у виняткових випадках
Елемент -частина блоку, але оскільки БЕМ-дерево незалежно від HTML-дерева, елемент можна використовувати і поза його блокомв деяких виняткових умовах(сам блок повинен бути на сторінці).
Приклад: розташування попапа-елемента не всередині блока-батька, а наприкінці DOM (щоб показувати попап незалежно від обмеження видимості батьків).
Якщо Ви використовуєте БЕМ лише як метод іменування селекторів, під час написання розмітки ніколи не використовуйте елемент поза блоком.
Чому не можна просто так розташовувати елемент поза блоком:
- втрачається логіка розмітки,
- складно стилізувати елементи, які можуть виявитися будь-де (float, абс. позиціонування та деякі інші стилі такого елемента можуть «зламати» верстку).
Елементів може не бути
Не у всіх блоків повинні бути елементи: кнопка завжди БЕМ-блок, але БЕМ-елементи у неї всередині зустрічаються відносно рідко.
Як відрізнити БЕМ-блок та БЕМ-елемент
Просто запитайте себе: «Ця сутність може знадобитися мені окремо, сама по собі? Чи вона потрібна лише всередині її батька? Якщо потрібна окремо - це БЕМ-блок, якщо можливатільки всередині батька – це БЕМ-елемент.
У дійсно сумнівних випадках робіть вибір на користь БЕМ-блоку.
Не забувайте про міксування (можливість мати на одному тезі і клас рівня БЕМ-елемента якогось батьківського блоку, і свій клас рівня БЕМ-блоку).
На всіх проектах (крім зовсім крихітних або мають нульову можливість модифікації) є фрагменти дизайну, які мудро завжди робити БЕМ-блоками через високу ймовірність повторення.
Деякі фрагменти дизайну завжди БЕМ-блоки
- Кнопка (будь-які кнопки)
- Блоки всередині форм (блок для текстового поля, блок для радіокнопки тощо)
- Пагінація
- Таби
- Лейбли (мітки)
- Соціальні посилання
- «Лайк» із лічильником
Модифікатор – додатковий клас для зміни оформлення чи поведінки
- Назва класу формується з назви блоку/елемента з додаванням - та назви модифікатора.
- Назва має бути простою і короткою.
- Назва класу може відповідати на запитання "Що це?", "Що змінюється?", "Чим відрізняється від інших?"
- Уникайте скорочень, крім найчастіших.
Модифікатор не можна використовувати самостійно
Клас модифікатор ніколи не повинен використовуватися самостійно, але завжди тільки з тим класом, який модифікує.
Міксування - комбінування на одному тегу класів БЕМ-блоку та БЕМ-елемента
Комбінація можлива у будь-якому поєднанні: БЕМ-блок + БЕМ-елемент, БЕМ-блок + БЕМ-блок, БЕМ-елемент + БЕМ-елемент. Цей підхід дозволяє:
- Додати деякі стильові властивості, потрібні тільки в місці додавання (використання модифікатора нераціонально). Приклад: для .btn всередині .page-header потрібен зовнішнійлівий відступ 37 пікс. Можна дописати до тега з .btn додатковий клас .page-header__btn і дати відступ за допомогою цього селектора.Це нормальна практика, її можна спокійно використовувати.
- Поєднати стилізацію 2-х і більше блоків. Приклад: для .article і .page-footer__section шрифтові властивості однакові. Можна винести визначення шрифтових властивостей до нового блоку .text і дописати цей клас на .article і .page-footer__section .Цей підхід надмірно зв'язує частини сторінки(нагадує OOCSS і клас-хелпер), не робіть так.
- Обійтися без тега-обгортки з селектором, що додається. Приклад: сторінка каталогу, 7+ товарів у потоці, кожен товар — .product, але кожному елементу потоку потрібні стильові властивості осередків модульної сітки (за якою побудовано потоковий висновок). Можна додати для .product клас комірки модульної сітки, щоб не робити обгортку з цим класом. Це загрожує конфліктом відступів/розмірів, не змішуйте на одному тегу класи обгортки та вмісту.
Класи БЕМ-блоків слід писати першими.
Міксування дещо погіршує сприйняття коду та збільшує ймовірність помилки змішування стилів, при якій ви пишите стильове правило в контексті не того селектора, де воно реально потрібне.
Один БЕМ-блок = один файл
У файловій системі при роботі з CSS-препроцесорами кожен БЕМ-блок повинен бути описаний у окремому файлі.
БЕМ-дерево плоске, на відміну від DOM
У класах БЕМ-елементів не можна прописувати ієрархію (два і більше сегмента неприпустимі).
Sass, LESS, Stylus, PostCSS.
Файлова організація
- Один БЕМ-блок = один препроцесорний файл. Завжди.
- Файл зі стилізацією БЕМ-блоку має називатися так само, як сам блок.
- Використовуйте «генераториблоків» (простий приклад, приклад складніший) для прискорення роботи.
- Компілюйте один файл (диспетчер підключень), в якому всі інші підключаються.
- Імпортуйте файли лише в диспетчері підключень (припустимо імпортувати домішки в окремому файлі, наприклад mixins.scss ).
- Не пишіть жодних селекторів у диспетчері підключень.
- Не імпортуйте файли в межах медіа-умов.
- Один БЕМ-блок = один препроцесорний файл.Завжди.
Вкладення селекторів
- Чим менше рівнів вкладеності, тим краще.
- Не допускайте більше 3-х рівнів вкладеності (псевдоелемени, псевдоселектори та медіа-умови не вважаються такими, що збільшують вкладеність).
- Обережно використовуйте жорстке успадкування.
- Завжди залишайте порожній рядок перед вкладеним селектором або @media.
- Завжди робіть додатковий відступ для вкладень.
- Вкладайте @media у селектори, а не навпаки.
- Не вкладайте @media один в одного.
- Віддайте перевагу шляху mobile-first, уникайте вказівки @media -умови max-width на користь min-width.
- Пишіть @media поряд, не пишіть селектори між ними.
- Пишіть умови для @media там, де використовуєте @media , не пишіть умови змінних.
- Використовуйте амперсанд тільки до:
- роздільником БЕМ-елемента,
- роздільником БЕМ-модифікатора,
- псевдоелементом чи псевдоселектором.
Черговість написання у контексті селектора
У контексті селекторавикористовуйте наступну черговість:
- Стильові правила для цього селектора.
- @media цього контексту.
- Псевдоселектори та псевдоелементи.
- Вкладені сторонні селектори.
- БЕМ-елементи.
- БЕМ-модифікатори.