Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Утилитарный CSS и CSS-модули

БЭМ решает проблему общего пространства имён договорённостью: люди сами следят, чтобы имена не совпадали. Есть два других пути. Первый — почти не придумывать имён, собирая вид из готовых маленьких классов. Второй — поручить уникальность имён инструментам сборки.

Утилитарные классы

Утилита — класс, который делает одну вещь: задаёт отступ, цвет или скругление. Подход utility-first («сначала утилиты») собирает внешний вид прямо в разметке из таких классов:

<style>
  .p-3 { padding: 12px; }
  .rounded { border-radius: 8px; }
  .border { border: 1px solid silver; }
  .bg-light { background: whitesmoke; }
  .bold { font-weight: bold; }
  .text-green { color: seagreen; }
</style>
 
<div class="p-3 rounded border bg-light">
  <div class="bold">Рюкзак</div>
  <div class="text-green">40 €</div>
</div>

В CSS нет ни одного правила про карточку — карточка получилась из сочетания утилит.

Tailwind

Самая известная библиотека утилит — Tailwind CSS. В ней тысячи готовых классов вроде p-4, bg-white, rounded-lg, hover:bg-gray-100, а в итоговый файл попадают только те, что встретились в разметке. Плюсы: не нужно придумывать имена, CSS почти не растёт, стили видны прямо в HTML. Минусы: длинные атрибуты class и необходимость выучить словарь классов.

CSS-модули

CSS-модули — функция сборщиков: программ, которые готовят код проекта к публикации. Вы пишете обычные короткие имена, а сборщик автоматически делает их уникальными, например .title превращается в .Card_title_x7f2:

/* Card.module.css содержит: .title { color: rebeccapurple; } */
import styles from './Card.module.css';
 
export function Card() {
  return <h3 className={styles.title}>Рюкзак</h3>;
}

Класс .title из этого файла никогда не столкнётся с .title другого компонента. Подход популярен в React-проектах.

Scoped-стили во фреймворках

JavaScript-фреймворки Vue, Svelte и Angular умеют ограничивать стили компонентом: правила из блока стилей действуют только на его разметку. Во Vue для этого есть атрибут scoped:

<template>
  <h3 class="title">Рюкзак</h3>
</template>
 
<style scoped>
.title { color: rebeccapurple; }
</style>

Конфликтов имён нет, а мёртвый CSS удаляется вместе с файлом компонента.

Что выбрать

СитуацияПодходящий подход
Обычный сайт без фреймворкаБЭМ, при желании с Sass и @layer
Быстрые прототипы, маленькая командаутилиты или Tailwind
Проект на ReactCSS-модули или Tailwind
Проект на Vue или Sveltescoped-стили

Подходы смешивают: компоненты по БЭМ или в модулях плюс десяток утилит вроде .visually-hidden. Главное — чтобы команда договорилась.

Частая ошибка

Копировать один и тот же длинный набор утилит в каждое место:

<style>
  .px-3 { padding: 6px 12px; } .rounded { border-radius: 6px; } .bg-green { background: seagreen; }
  .text-white { color: white; } .no-border { border: none; }
</style>
 
<button class="px-3 rounded bg-green text-white no-border">Купить</button>
<button class="px-3 rounded bg-green text-white no-border">В корзину</button>
<button class="px-3 rounded bg-green text-white no-border">Оформить</button>

Чтобы поменять цвет всех кнопок, придётся исправить каждую. Повторяющийся набор выносят в компонент фреймворка или в обычный класс .button.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.