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