На главную

: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 — это первый тег».