如何更改CSS:JavaScript中的根颜色变量

Dae*_*lus 26 html javascript css

好吧,我正在为我的网页创建一个系统,允许用户更改主题.我想要实现这一点的方法是将所有颜色作为变量,并在CSS的根部分中设置颜色.

我想要做的是通过JavaScript更改这些颜色.我抬头看看怎么做,但我尝试过的任何事情都没有.这是我目前的代码:

CSS:

:root {
  --main-color: #317EEB;
  --hover-color: #2764BA;
  --body-color: #E0E0E0;
  --box-color: white;
}
Run Code Online (Sandbox Code Playgroud)

JS:

(设置主题的代码,单击按钮运行) - 我没有费心将:root更改添加到其他2个主题,因为它不适用于Dark主题

function setTheme(theme) {
  if (theme == 'Dark') {
    localStorage.setItem('panelTheme', theme);
    $('#current-theme').text(theme);
    $(':root').css('--main-color', '#000000');
  }
  if (theme == 'Blue') {
    localStorage.setItem('panelTheme',  'Blue');
    $('#current-theme').text('Blue');
    alert("Blue");
  }
  if (theme == 'Green') {
    localStorage.setItem('panelTheme', 'Green');
    $('#current-theme').text('Green');
    alert("Green");
  }
}
Run Code Online (Sandbox Code Playgroud)

(加载html时运行的代码)

function loadTheme() {
  //Add this to body onload, gets the current theme. If panelTheme is empty, defaults to blue.
  if (localStorage.getItem('panelTheme') == '') {
    setTheme('Blue');
  } else {
    setTheme(localStorage.getItem('panelTheme'));
    $('#current-theme').text(localStorage.getItem('panelTheme'));
  }
}
Run Code Online (Sandbox Code Playgroud)

它显示警报,但实际上并没有改变任何东西.有人能指出我正确的方向吗?

Dae*_*lus 52

感谢@pvg提供链接.我不得不盯着它看一下才知道发生了什么,但我终于明白了.

我正在寻找的神奇线条是这样的:

document.documentElement.style.setProperty('--your-variable', '#YOURCOLOR');
Run Code Online (Sandbox Code Playgroud)

这完全是我想要它做的,非常感谢你!

  • 我喜欢使用 `document.querySelector(":root")` 而不是 `document.documentElement`,因为我确信这与 css 中的 `:root { ... }` 是相同的元素 (14认同)
  • 获取值的方式是:`getComputedStyle(element).getPropertyValue("--my-var");` (8认同)
  • `document.querySelector(':root') === document.documentElement` 返回 `true` - 然而,TypeScript 抱怨前一个;我怀疑它抱怨有充分的理由:/ (3认同)
  • 具有讽刺意味的是,看起来 getPropertyValue 没有使用 :root css 变量,但设置确实如此 (2认同)

Pak*_*kit 24

我认为这样更清晰、更容易记住。设置/获取 css 变量:root

const root = document.querySelector(':root');

// set css variable
root.style.setProperty('--my-color', 'blue');

// to get css variable from :root
const color = getComputedStyle(root).getPropertyValue('--my-color'); // blue
Run Code Online (Sandbox Code Playgroud)

示例:一次设置多个变量

const setVariables = vars => Object.entries(vars).forEach(v => root.style.setProperty(v[0], v[1]));
const myVariables = {
  '--color-primary-50': '#eff6ff',
  '--color-primary-100': '#dbeafe',
  '--color-primary-200': '#bfdbfe',
  '--color-primary-300': '#93c5fd',
  '--color-primary-400': '#60a5fa',
  '--color-primary-500': '#3b82f6',
  '--color-primary-600': '#2563eb',
  '--color-primary-700': '#1d4ed8',
  '--color-primary-800': '#1e40af',
  '--color-primary-900': '#1e3a8a',
};
setVariables(myVariables);
Run Code Online (Sandbox Code Playgroud)


Mic*_*ael 11

对于那些想要修改实际样式表的人,以下工作:

var sheet = document.styleSheets[0];
sheet.insertRule(":root{--blue:#4444FF}");
Run Code Online (Sandbox Code Playgroud)

更多信息请访问:https : //developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/addRule

  • 我刚刚发现“setProperty”也许做了类似的事情。所以我想知道这是否也有效?`document.body.style.setProperty('--blue', '#4444ff');` 你觉得怎么样? (2认同)
  • @edwardsmarkf 这种方式正在改变 DOM,而上面的代码正在改变样式表本身。更改样式表允许主题动态更改而无需重新加载。当颜色值更改时,所有使用 --blue 变量的元素都会立即更改。对于 DOM,您必须更改要更新的每个元素。 (2认同)

小智 8

在 JavaScript 中使用自定义属性的值,就像使用标准属性一样。

// get variable from inline style
element.style.getPropertyValue("--my-variable");

// get variable from wherever
getComputedStyle(element).getPropertyValue("--my-variable");

// set variable on inline style
element.style.setProperty("--my-variable", 4);
Run Code Online (Sandbox Code Playgroud)

  • 第一个示例不适用于 `:root` css 属性 - 它仅适用于直接使用 `setProperty` 设置的值。需要使用 `getComputedStyle(element).getPropertyValue(......)` (4认同)

小智 5

我来到这里寻找如何使用 JavaScript 切换:root 颜色方案,它将浏览器设置为深色模式(包括滚动条),如下所示:

:root {
    color-scheme: dark;
}
Run Code Online (Sandbox Code Playgroud)

使用上面的 @Daedalus 答案,这就是我根据用户偏好实现暗模式检测的方法:

    const userPrefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
    const preferredTheme = userPrefersDarkMode ? 'dark' : 'light';
    document.documentElement.style.setProperty("color-scheme", preferredTheme);

Run Code Online (Sandbox Code Playgroud)

或使用保存的切换:

    const savedTheme = localStorage.getItem('theme');
    if (savedTheme == 'dark') {
        thisTheme = 'light'
    }
    else {
        thisTheme = 'dark'; // the default when never saved is dark
    }
    document.documentElement.style.setProperty("color-scheme", thisTheme);
    localStorage.setItem('theme', thisTheme);
Run Code Online (Sandbox Code Playgroud)

另请参阅标头中的可选元标记:

<meta name="color-scheme" content="dark light">
Run Code Online (Sandbox Code Playgroud)


Joh*_*dis 5

长话短说

该问题的解决方案可能是以下代码:

const headTag = document.getElementsByTagName('head')[0];
const styleTag = document.createElement("style");

styleTag.innerHTML = `
:root {
    --main-color: #317EEB;
    --hover-color: #2764BA;
    --body-color: #E0E0E0;
    --box-color: white;
}
`;
headTag.appendChild(styleTag);
Run Code Online (Sandbox Code Playgroud)

解释:

尽管 @Daedalus 的回答document.documentElement很好地完成了这项工作,但更好的方法是将样式添加到<style>HTML 标记中(建议的解决方案)。

如果添加document.documentElement.style,则所有 CSS 变量都会添加到标签中html,并且不会隐藏:

CSS 样式内联到 html

另一方面,使用建议的代码:

const headTag = document.getElementsByTagName('head')[0];
const styleTag = document.createElement("style");

styleTag.innerHTML = `
:root {
    --main-color: #317EEB;
    --hover-color: #2764BA;
    --body-color: #E0E0E0;
    --box-color: white;
}
`;
headTag.appendChild(styleTag);
Run Code Online (Sandbox Code Playgroud)

HTML 标签会更干净,如果您检查 HTML 标签,您还可以看到样式:root

没有样式的 HTML 标签