А что если реальная проблема вашего CSS не в том, что он глобальный, а в том, что вы никогда не определили, что такое UI-единица?
Вы знаете это чувство. Вы меняете padding на одном экране. И вдруг кнопка в десяти файлах дальше выглядит неправильно. Один и тот же HTML отрисовывается по-разному в разных контекстах. Вы уже не можете сказать, какое правило отвечает за то, что видно на экране. Поэтому вы добавляете ещё один селектор для подстраховки. Потом ещё один. И вот ваша таблица стилей становится археологическими раскопками, а компонент выглядит так, будто его писал целый комитет.
Большинство команд винят в этом CSS. Они ошибаются.
Реальная проблема не в CSS—она в структуре
Вот что на самом деле происходит: ваш HTML живёт в одном месте, CSS в другом, а DOM-поведение в третьем. Каждая часть выглядит нормально отдельно. Но все они описывают один и тот же визуальный блок, никогда не находясь в одном месте.
В этом зазоре и живёт дрейф.
HTML в одиночку не говорит вам, как ведёт себя элемент. CSS не говорит вам, к какой структурной единице он относится. DOM-код модифицирует ту же область без контекста стилизации или изначального намерения. У вас три разные команды работают над одним сотрудником, говорят на разных языках и никогда не синхронизируются.
“Проблема была в том, что не было чёткой UI-единицы, которая объединяла бы эти ответственности. Без этой единицы небольшие исправления накапливаются в зазорах между файлами.”
Они действительно накапливаются. Селектор подстраивается. Правило добавляется. Появляется DOM-патч. Каждое по отдельности логично. Но экран в целом становится непонятным.
Один разработчик, работавший с Razor Pages, заметил что-то интересное. Пара .cshtml и .cshtml.css создавала отношение—CSS автоматически скопирован в пределах этой страницы. Радиус влияния был небольшим по умолчанию. Вы могли реализовать стили без постоянного беспокойства о том, не сломали ли вы что-то три слоя глубже в другом файле.
Это было не идеально. Но это сделало одно очевидным: когда связанные ответственности остаются привязанными к единице, к которой они относятся, они перестают вытекать везде.
Что реально принадлежит UI-единице?
Эта реализация привела к другому вопросу: а что если HTML и CSS должны оставаться привязанными к значимой границе в коде фронтенда, как это показали Razor Pages?
Вместо того чтобы думать о свободных слоях—разметка здесь, стилизация там, поведение плывёт где-то—вы начинаете думать в терминах владения элементом. Одна граница владеет одним структурным корнем, одним локальным контекстом стилизации и одним местом, где живёт DOM-поведение. Потому что эта граница становится единственным местом, где структура, стиль и поведение могут встретиться, изменения перестают вытекать.
Это не о превращении всего в фреймворк компонентов. Это о наличии единицы, достаточно маленькой, чтобы владеть собственной структурой.
Представьте себе что-то простое, называемое ElementBoundary:
const profileCard = new ElementBoundary(
/* html */ `
<section>
<h2 class="title">Profile</h2>
<p class="value">Active</p>
</section>
`,
/* css */ `
[root] {
padding: 12px;
border: 1px solid #d0d7de;
}
[root] .title {
font-size: 14px;
margin: 0 0 8px;
}
`
);
const screen = ElementBoundary.first("#screen");
screen.append(profileCard);
Конструктор не важен. Важно то, что одна элементная единица владеет как своим HTML, так и CSS. Контейнер экрана обрабатывается через ту же модель граница вместо того, чтобы возвращаться к сырому DOM-доступу. Заполнитель [root] автоматически переписывается в селектор, специфичный для граница, поэтому CSS применяется только внутри этой единицы.
Это не Shadow DOM. Shadow DOM выводит вас из нормального потока DOM. Это держит вас в нём, одновременно давая вам более узкую границу стилизации, которая масштабируется по мере роста интерфейса. Создание, поиск и размещение всё следуют одной модели вместо того, чтобы быть несвязанными DOM-операциями, разбросанными по всей кодовой базе.
Почему это действительно решает проблему дрейфа
Когда вы начинаете думать так, меняются три вещи.
CSS становится локальным, потому что он привязан к корню элемента вместо того, чтобы рассматриваться как отдельный глобальный слой. DOM-поведение становится легче размещать, потому что оно принадлежит конкретной единице вместо того, чтобы плыть по странице. Сам интерфейс начинает рассматриваться согласованно—как существующие области, так и вновь созданные следуют одному структурному смыслу.
Вы перестаёте спрашивать какой селектор отвечает? и начинаете спрашивать какая граница владеет этим? Это совсем другой разговор.
Пробел между тем, что описывает ваш HTML, что делает ваш CSS, что делает ваш DOM-код—этот пробел исчезает. Не потому, что вы использовали фреймворк. Потому что вы определили, что такое единица.
Это важно, потому что масштабируемые фронтенды не падают из-за синтаксиса CSS. Они падают, потому что команды никогда не договорились, где начинается и заканчивается ответственность. Когда вы определяете чёткую границу, эта неопределённость умирает. Вы можете менять вещи без страха. Вы можете добавлять функции без создания технического долга. И вы можете знакомить новых разработчиков без необходимости реконструировать всю вашу стратегию стилизации.
Это не революционно. Это структурно.
🧬 Связанные идеи
- Прочитайте также: Higress присоединился к CNCF как AI Gateway ставка Alibaba—и Nginx есть до 2026 года на беспокойство
- Прочитайте также: Claude Code’s Token Collapse: When AI Pricing Models Break Developer Workflows
Часто задаваемые вопросы
Заменят ли DOM-границы фреймворки компонентов вроде React? Нет. Это о структурной организации в любом используемом вами фреймворке. React-компоненты могли бы принять этот паттерн. Простой JavaScript тоже. Граница—это про ответственность, а не про инструментарий.
Работает ли это с существующим CSS? Да, если вы можете переделать селекторы, чтобы уважать область граница. Новые проекты принимают это сразу. Старый код требует переписывания, но оно ограничено одной единицей за раз.
Это то же самое, что CSS modules? Похожая цель, другой подход. CSS modules используют соглашения об именовании и инструментарий. Границы делают структурную единицу явной в вашем JavaScript, связывая HTML, CSS и поведение вместе концептуально, а не только технически.