Dmitry Grenev

CSS: методологии организации

CSS кажется простым до тех пор, пока проект не начинает расти вместе с командой. В этот момент стили становятся архитектурой: у классов появляется ответственность, у папок — структура, у компонентов — правила расширения.

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

Методология снижает стоимость изменений. Хорошая CSS-архитектура помогает быстрее рефакторить интерфейс, добавлять новые компоненты и понимать, где находится нужное правило.

В основе популярных подходов обычно лежит один из двух принципов. Write Everything Twice (WET) делает ставку на семантичные классы и понятные компоненты. Don’t Repeat Yourself (DRY) выносит повторяемые свойства в переиспользуемые утилиты. Оба подхода платят свою цену: WET плодит дублирование в CSS, DRY переносит часть сложности в HTML.

Качество методологии видно по трём признакам:

① Гибкость — стили можно менять и рефакторить без каскада случайных поломок;

② Масштабируемость — новые компоненты входят в систему без локальных исключений;

③ Доступность — разработчики понимают, как писать, искать и изменять стили.

Ниже — три способа организовать CSS: OOCSS, BEM и Atomic CSS.

1.1

OOCSS

Идеология — функциональная.

Означает объектно-ориентированный CSS (Object-Oriented CSS). Основной постулат — разделение стилей элемента на структуру и оформление.

К стилям структуры можно отнести высоту, ширину, паддинги, маржины и все, что влияет на расположение элемента на странице и контента внутри.

К стилям оформления — цвета, скругления, тени и прочие декоративные свойства.

.ctrl-1 {
  padding: 20px;
  width: fit-content;
}

.ctrl-2 {
  padding: 12px 24px;
  width: fit-content;
}

.ctrl-primary {
  background: black;
  color: white;
  border-radius: 12px;
}

.ctrl-secondary {
  border: 1px solid black;
  color: black;
  border-radius: 48px;
}

browser

1234

В примере выше я показал кнопку с четырьмя вариантами комбинаций стилей оформления и структуры.

Если нужно изменить структуру кнопок ① и ③, достаточно поправить класс .ctrl-1: оформление останется в своих классах.

Моя субъективная оценка по 5-балльной шкале:

Гибкость — 4 Масштабируемость — 4 Доступность — 4

1.2

BEM

Идеология — семантичная.

БЭМ — акроним от слов Блок, Элемент, Модификатор. Придумали в Яндексе и сейчас его используют по всему миру.

Блоки — это компоненты, которые могут переиспользоваться множество раз в рамках проекта, элементы — составная часть конкретного блока, а модификаторы отвечают за свойства блока или элемента, которые меняют его внешний вид или поведение. Каждый из них является классом со своим назначением.

У БЭМа есть свои правила написания классов:

.имя-блока__имя-элемента_имя-модификатора

Есть такой неофициальный, но более читабельный вариант:

.имя-блока__имя-элемента--имя-модификатора.

Используем второй для примера.

.form {
  display: grid;
  padding: 16px;
  grid-gap: 16px;
  border: 1px solid #AAAAAA;
  border-radius: 16px;
  width: fit-content;
}

.form__ctrl {
  width: fit-content;
}

.form__ctrl--primary {
  background: black;
  color: white;
  border-radius: 12px;
  padding: 20px;
}

.form__ctrl--secondary {
  border: 1px solid black;
  color: black;
  border-radius: 48px;
  padding: 12px 48px;
}

browser

Press:

В примере блок .form содержит две кнопки. Если стили .form__ctrl и модификаторов понадобятся за пределами .form, их придётся заново описывать в другом блоке и другом нейминге. Это главная цена семантичного подхода: компоненты хорошо изолированы, но их элементы хуже переиспользуются вне родительского контекста.

Исторически БЭМ снижал риск каскада и специфичности через отказ от сложных селекторов в пользу классов. Сегодня часть этой задачи можно решать и другими средствами, например CSS Layers.

Моя субъективная оценка:

Гибкость — 4 Масштабируемость — 3 Доступность — 5

1.3

Atomic

Идеология — функциональная.

Суть метода — раздробить стили на классы с одним свойством и значением, а затем собирать из них элементы в HTML. Подход похож на OOCSS, но атомарные классы значительно мельче: каждый отвечает за одну декларацию.

Пример атомарных классов:

C(#fff) — color: #fff; w-100 — width: 100%; mt-12 — margin-top: 12px;

Такие классы можно писать прямо в HTML, подключив заранее собранную атомарную библиотеку. Они переиспользуются в разных элементах по всему проекту и не привязаны к конкретному блоку, как элементы и модификаторы БЭМа. Сильная сторона атомов — быстрая настройка конкретного элемента.

Цена подхода — повторяющиеся наборы классов в похожей разметке. Без компонентного слоя одинаковые элементы сложнее менять одновременно. Кроме того, библиотека обычно содержит больше классов, чем реально используется, поэтому сборка должна отсекать лишнее.

.pad-20 {
  padding: 20px;
}

.pad-12-24 {
  padding: 12px 24px;
}

.c-F {
  color: white;
}

.c-0 {
  color: black;
}

.b-0 {
  border: solid black;
}

.wid-fit {
  width: fit-content;
}

.bg-0 {
  background: black;
}

.br-12 {
  border-radius: 12px;
}

.br-48 {
  border-radius: 48px;
}

.b-1 {
  border: 1px;
}

browser

1234

Здесь видна та же закономерность, что и в примере с OOCSS — кнопки собираются из множества классов. Только теперь каждый класс отвечает за одно свойство.

Моя субъективная оценка:

Гибкость — 4 Масштабируемость — 5 Доступность — 3

1.4

Заключение

На практике методология становится архитектурой только после адаптации под проект. Выбирайте подход по тому, какие изменения команда делает чаще всего: добавляет компоненты, меняет оформление, переиспользует утилиты или поддерживает большой набор однотипных экранов. Хорошая система сохраняет договорённости видимыми в коде.

2026