Ответ 1
Это, откровенно говоря, лучший (как и в большинстве идиоматических) подход - использование имен классов, если не вообще отдельных таблиц стилей (как это было уже много-много лет), для оформления целых макетов с помощью пользовательских свойств. Это наиболее "фундаментально CSS" подход с JavaScript, просто являющийся клеем, который заставляет переключение темы работать. Вы действительно не можете сделать намного лучше, чем это.
Для тех, кто не знает, что означает :root
и интересуется, где именно применяются имена классов, это html
элемент (родительский элемент body
). Так что здесь ничего особенного не происходит - вы просто переключаете имена классов в элементе html
. Просто бывает, что глобальные пользовательские свойства традиционно определены для корневого элемента документа, поскольку он находится на верхнем уровне цепочки наследования.
Если у вас есть какие-либо не зависящие от темы пользовательские свойства, а также свойства стиля (т.е. Не настраиваемые свойства), которые применяются к корневому элементу, оставьте их в своем собственном неквалифицированном :root
правило, отделенное от ваших тематических настраиваемых свойств, чтобы они не быть затронутым переключением темы. Вот пример:
const root = document.documentElement;
// Default theme - should assign declaratively in markup, not JS
// For a classless default theme, move its custom properties to unqualified :root
// Again, keep it separate from the other :root rule that contains non-theme props
// Remember, the cascade is your friend, not the enemy
root.classList.add('white');
document.querySelector('button').addEventListener('click', function() {
root.classList.toggle('white');
root.classList.toggle('black');
});
:root {
--spacing: 1rem;
color: var(--col);
background-color: var(--bgcol);
}
:root.white {
--bgcol: #FFF;
--col: #000;
}
:root.black {
--bgcol: #000;
--col: #FFF;
}
p {
margin: var(--spacing);
border: thin dashed;
padding: var(--spacing);
}
<button>Switch themes</button>
<p>Hello world!