我可以将类名添加到 CSS 变量吗?

Can I add a classname to a CSS variable?

是否可以将 class 名称添加到 CSS 变量,或者是否有其他设置方法,这样我就不必直接通过 javascript?我想将所有样式保留在 CSS 中,并使用 JS 简单地打开相关的 classes。例如,如果这样的事情在 CSS:

中是可能的
:root.white{ --bgcol:#FFF; --col:#000; }
:root.black{ --bgcol:#000; --col:#FFF; }

然后我可以从 javascript 切换 .black.white class 来触发所有变量的改变。此类设置的最佳方法是什么?

坦率地说,这是最好的(如最惯用的)方法 — 使用 class 名称,如果不是完全独立的样式表 (as has been tradition for many, many years),则通过自定义属性为整个布局设置主题。这是最 "fundamentally CSS" 的方法,JavaScript 只是使主题切换起作用的粘合剂。你真的没有比这更好的了。

对于那些不知道 :root 是什么意思并想知道 class 名称究竟应用在哪里的人,这是 html 元素(body 的父元素)。所以这里没有什么特别的——你只是在 html 元素上切换 class 名称。碰巧全局自定义属性通常是为文档根元素定义的,因为它位于继承链的顶层。

如果您有任何与主题无关的自定义属性,以及适用于根元素的样式属性(即非自定义属性),请将它们保留在自己的非限定 :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!

使用:root选择器与使用html相同,只是它的特异性更高,因此使用这种方法没有问题。

例如:

:root {
  --bg: red;
}
:root.blue {
  --bg: blue;
}
// ...
div {
  background: var(--bg);
}

稍后,您只需更改 html 的 class,变量就会发生变化。

你可以看一个例子in this fiddle