Сравни BEM и подход utility-first, их реальные компромиссы в команде, и выстрой свои файлы через слои каскада.
Открыть этот урок в KodokonCSS ломается не на масштабе компонента, а на масштабе проекта: специфичность растёт только ради того, чтобы «победить» существующее правило, страшно удалять код, охват которого тебе неизвестен, стили протекают с одного экрана на другой. Архитектура CSS - это прежде всего стратегия управления специфичностью и областью действия. Две доминирующие школы, BEM и utility-first, отвечают на одну и ту же задачу противоположными путями.
BEM (Block, Element, Modifier) даёт имя каждому стилизованному узлу: .card (самостоятельный блок), .card__title (элемент, принадлежащий блоку), .card--featured (вариант блока). Соглашение гарантирует плоскую специфичность - везде один класс, никаких селекторов потомков - а значит, никаких конфликтов порядка, плюс имя, которое документирует принадлежность. Цена: приходится постоянно придумывать имена, и появляется настоящее дублирование значений (один и тот же margin-top: 16px, переписанный в двадцати блоках).
.card {
padding: 16px;
border-radius: 8px;
}
.card__title {
font-size: 1.25rem;
}
.card__title--muted {
color: #6b7280;
}
.card--featured {
border: 2px solid var(--brand);
}Подход utility-first (Tailwind - его главное воплощение) переворачивает логику: никаких имён, только атомарные классы с одной ответственностью, которые компонуются прямо в HTML. Выгоды измеримы: нулевые затраты на именование, стили лежат рядом с разметкой (удалил компонент - удалил и его стили), а итоговый CSS-бандл почти не растёт в размере, потому что утилиты переиспользуются. Компромиссы тоже есть: многословный HTML, дублирование, перенесённое в разметку и требующее слоя компонентов (React, Vue, частичные шаблоны), чтобы остаться DRY, и кривая обучения словарю.
<article class="flex flex-col gap-4 rounded-lg
border border-gray-200 p-4 shadow-sm">
<h2 class="text-lg font-semibold">Invoice</h2>
<p class="text-sm text-gray-600">
Paid on March 12
</p>
</article>Эти подходы не исключают друг друга: многие зрелые команды их совмещают - утилиты для раскладки и отступов, классы компонентов (BEM или CSS Modules) для сложных паттернов и состояний. Что до организации файлов, принцип ITCSS остаётся ориентиром: порядок от общего к частному (сброс, базовые элементы, компоненты, утилиты). Нативное правило @layer превращает это соглашение в гарантию на уровне движка: приоритет между слоями не зависит от специфичности содержащихся в них селекторов.
@layer reset, base, components, utilities;
@layer base {
h2 { font-size: 1.5rem; }
}
@layer components {
#hero .btn { padding: 12px 24px; }
}
@layer utilities {
.p-0 { padding: 0; }
}--muted в .card__title--muted?card__titlecard__title@layer привносит в каскад?