:root и html — это не одно и то же, и разделять их нормально
В прошлой статье я говорил о том, что :root — это просто селектор с лишней специфичностью, и что хранить там кастомные свойства совсем не обязательно. Но в обсуждениях я понял одну вещь: разделять :root и html не только можно, но и удобно.
Зачем вообще держать :root?
Во-первых, :root удобно вынести в отдельный файл. Точно так же, как мы когда-то клали переменные в variables.scss.
Например:
/* variables.css */
:root {
--color-text: #111;
--color-link: rebeccapurple;
}
А в другом файле можно держать переменные для inline-svg, чтобы они не мешались с глобальными:
/* svg-variables.css */
:root {
--icon-color: currentColor;
}
Так появляется структура: глобальные переменные — в :root, локальные — где угодно.
А что с html?
html как селектор остаётся полезным.
Например, для ресета или конкретных «поведенческих» стилей: sticky-footer, scroll-behavior, overflow-y.
Логично: html — это тег верхнего уровня, который можно стилизовать. А :root — это как бы уровень документа в целом.
Концепция
Если «задушниться» то :root — это не просто синоним html. Это абстракция над всем документом.
html — это первый элемент, но он не документ. Отличная фраза, которую я удачно запомнил для себя из обсуждений
Когда мы кладём глобальные переменные в :root, мы не стилизуем html. Мы конфигурируем весь документ. Удобнее держать «глобальные» и «теговые» вещи в разных местах.
Примерно так же, как в React:
main.tsx— уровень конфигурации (провайдеры, роутер, глобальные настройки).App.tsx— первый реальный компонент.
html ближе к App, а :root — это условный main. У меня даже такие аналогии есть.
А как же специфичность?
Сегодня этот вопрос почти не стоит.
Во-первых, есть @layer, и порядок слоёв решает больше, чем селектор.
Во-вторых, мы всё равно переопределяем переменные там, где нужно: на уровне компонента, контейнера, body или html.
Итог
:root — это не магия, а соглашение. Но соглашение удобное.
:root— для глобальных переменных и документа.html— для реальных стилей элемента верхнего уровня.
Разделять эти два уровня абсолютно нормально. И если раньше казалось, что :root — это просто избыточность, то сейчас я вижу в этом смысловую границу.
«
:root— это конфигурация документа,html— это первый тег».