首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何覆盖css偏好-配色方案设置

如何覆盖css偏好-配色方案设置
EN

Stack Overflow用户
提问于 2019-05-24 22:28:14
回答 11查看 57.3K关注 0票数 65

我正在实现一种黑暗模式,因为macOS、iOS和Windows都引入了黑暗模式。

Safari、Chrome和Firefox有一个本机选项,使用以下CSS媒体规则:

代码语言:javascript
复制
@media (prefers-color-scheme: dark) {
body {
    color:#fff;
    background:#333333
}

这将自动识别被设置为暗模式的系统,并应用封闭的CSS规则。

然而,即使用户的系统设置为黑暗模式,也可能是因为他们更喜欢某个特定网站的轻量或默认主题。Microsoft用户也不支持@media (prefers-color-scheme。为了获得最好的用户体验,我希望确保这些用户能够在这些情况下切换黑暗模式和默认模式。

是否有一种方法可以执行,可能是使用HTML5或JavaScript?我会包括我尝试过的代码,但是我没有找到任何关于实现这一点的信息!

EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2019-06-11 19:50:00

我已决定了一个适当的解决办法,具体如下:

CSS将使用变量和主题:

代码语言:javascript
复制
// root/default variables
:root {
    --font-color: #000;
    --link-color:#1C75B9;
    --link-white-color:#fff;
    --bg-color: rgb(243,243,243);
}
//dark theme
[data-theme="dark"] {
    --font-color: #c1bfbd;
    --link-color:#0a86da;
    --link-white-color:#c1bfbd;
    --bg-color: #333;
}

然后在必要时调用这些变量,例如:

代码语言:javascript
复制
//the redundancy is for backwards compatibility with browsers that do not support CSS variables.
body
{
    color:#000;
    color:var(--font-color);
    background:rgb(243,243,243);
    background:var(--bg-color);
}

JavaScript用于标识用户设置了哪个主题,或者如果他们重写了OS主题,并且在两者之间切换,这包括在html <body>...</body>输出之前的标题中。

代码语言:javascript
复制
//determines if the user has a set theme
function detectColorScheme(){
    var theme="light";    //default to light

    //local storage is used to override OS theme settings
    if(localStorage.getItem("theme")){
        if(localStorage.getItem("theme") == "dark"){
            var theme = "dark";
        }
    } else if(!window.matchMedia) {
        //matchMedia method not supported
        return false;
    } else if(window.matchMedia("(prefers-color-scheme: dark)").matches) {
        //OS theme setting detected as dark
        var theme = "dark";
    }

    //dark theme preferred, set document with a `data-theme` attribute
    if (theme=="dark") {
         document.documentElement.setAttribute("data-theme", "dark");
    }
}
detectColorScheme();

此javascript用于在设置之间切换,它不需要包含在页面的标题中,而是可以包含在任何地方。

代码语言:javascript
复制
//identify the toggle switch HTML element
const toggleSwitch = document.querySelector('#theme-switch input[type="checkbox"]');

//function that changes the theme, and sets a localStorage variable to track the theme between page loads
function switchTheme(e) {
    if (e.target.checked) {
        localStorage.setItem('theme', 'dark');
        document.documentElement.setAttribute('data-theme', 'dark');
        toggleSwitch.checked = true;
    } else {
        localStorage.setItem('theme', 'light');
        document.documentElement.setAttribute('data-theme', 'light');
        toggleSwitch.checked = false;
    }    
}

//listener for changing themes
toggleSwitch.addEventListener('change', switchTheme, false);

//pre-check the dark-theme checkbox if dark-theme is set
if (document.documentElement.getAttribute("data-theme") == "dark"){
    toggleSwitch.checked = true;
}

最后,要在主题之间切换的HTML复选框:

代码语言:javascript
复制
<label id="theme-switch" class="theme-switch" for="checkbox_theme">
    <input type="checkbox" id="checkbox_theme">
</label>

通过使用CSS变量和JavaScript,我们可以自动确定用户主题,应用它,并允许用户超越它。截至编写本报告的当前时间(2019/06/10),只有Firefox和Safari支持自动主题检测

票数 85
EN

Stack Overflow用户

发布于 2021-08-17 21:43:10

不知道为什么所有的答案都这么复杂。

像往常一样,在媒体查询中使用CSS变量,设置默认值和相反的值。还可以在两个类中设置值。实现一个当单击这些类时切换这些类的切换。

默认情况下,基于系统配色方案使用自动光/暗模式。使用切换开关到手动光/暗模式。在刷新页面(或从html元素中移除类)后,它返回到自动光照/黑暗模式。

代码语言:javascript
复制
// toggle to switch classes between .light and .dark
// if no class is present (initial state), then assume current state based on system color scheme
// if system color scheme is not supported, then assume current state is light
function toggleDarkMode() {
  if (document.documentElement.classList.contains("light")) {
    document.documentElement.classList.remove("light")
    document.documentElement.classList.add("dark")
  } else if (document.documentElement.classList.contains("dark")) {
    document.documentElement.classList.remove("dark")
    document.documentElement.classList.add("light")
  } else {
    if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
      document.documentElement.classList.add("dark")
    } else {
      document.documentElement.classList.add("light")
    }
  }
}
代码语言:javascript
复制
/* automatic/manual light mode */
:root, :root.light {
  --some-value: black;
  --some-other-value: white;
}

/* automatic dark mode */
/* ❗️ keep the rules in sync with the manual dark mode below! */
@media (prefers-color-scheme: dark) {
  :root {
    --some-value: white;
    --some-other-value: black;
  }
}

/* manual dark mode 
/* ❗️ keep the rules in sync with the automatic dark mode above! */
:root.dark {
  --some-value: white;
  --some-other-value: black;
}

/* use the variables */
body {
  color: var(--some-value);
  background-color: var(--some-other-value);
}
代码语言:javascript
复制
<button onClick="toggleDarkMode()">Toggle</button>
<h1>Hello world!</h1>

票数 13
EN

Stack Overflow用户

发布于 2019-08-23 06:37:06

您可以使用我的自定义元素,它最初遵循用户的prefers-color-scheme设置,但也允许用户(永久或临时)覆盖它。该切换既适用于单独的CSS文件,也适用于切换的类。自述文件有这两种方法的示例。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56300132

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档