CSS 中的暗黑模式指南

Avatar of Adhuham
Adhuham 发布

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 $200 免费信用额度!

暗黑模式最近获得了很大关注。 例如,Apple 已将其 iOS 和 MacOS 操作系统添加了暗黑模式。 Windows 和 Google 也一样。

DuckDuckGo 的亮色和暗黑主题

让我们从 **网站** 的角度深入了解暗黑模式。 我们将深入探讨实现暗黑模式设计的不同选项和方法,以及它们带来的技术考虑因素。 我们还将介绍一些设计技巧。


切换主题

典型情况是您已经为您的网站创建了一个亮色主题,并且您希望创建一个更暗的对应主题。 或者,即使您从头开始,您也会有两种主题:亮色和暗黑。 其中一个主题应被定义为用户首次访问时获得的默认主题,在大多数情况下是亮色主题(尽管我们可以让用户的浏览器为我们做出这个选择,正如我们将在后面看到的那样)。 还应该有一种方法可以切换到另一个主题(这可以自动完成,正如我们也将看到的那样)——例如,用户点击一个按钮,颜色主题就会发生变化。

有多种方法可以实现这一点

使用 Body 类

这里的诀窍是替换一个类,它可以作为页面上任何位置更改样式的钩子。

<body class="dark-theme || light-theme">

例如,这里是一个用于切换该类的按钮的脚本

// Select the button
const btn = document.querySelector('.btn-toggle');

// Listen for a click on the button
btn.addEventListener('click', function() {
  // Then toggle (add/remove) the .dark-theme class to the body
  document.body.classList.toggle('dark-theme');  
})

以下是我们可以使用该想法的方法

<body>
  <button class="btn-toggle">Toggle Dark Mode</button>
  <h1>Hey there! This is just a title</h1>
  <p>I am just a boring text, existing here solely for the purpose of this demo</p>
  <p>And I am just another one like the one above me, because two is better than having only one</p>
  <a href="#">I am a link, don't click me!</a>
</body>

这种方法的基本思路是像往常一样设置样式,将其称为我们的“默认”模式,然后使用一个在<body>元素上设置的类创建一个完整的颜色样式集,我们可以将其用作“暗黑”模式。

假设我们的默认主题是亮色方案。 所有这些“亮色”样式都以您通常编写 CSS 的方式编写。 鉴于我们的 HTML,让我们将一些全局样式应用于 body 和链接。

body {
  color: #222;
  background: #fff;
}
a {
  color: #0033cc;
}

很好。 我们在亮色背景 (#fff) 上有深色文本 (#222) 和深色链接 (#0033cc)。 我们的“默认”主题已经取得了一个良好的开端。

现在让我们重新定义这些属性值,这次将其设置在不同的 body 类上

body {
  color: #222;
  background: #fff;
}
a {
  color: #0033cc;
}


/* Dark Mode styles */
body.dark-theme {
  color: #eee;
  background: #121212;
}
body.dark-theme a {
  color: #809fff;
}

暗黑主题样式将是相同父类的后代——在本例中是.dark-theme——我们已将其应用于<body>标签。

我们如何“切换”body 类以访问暗黑样式? 我们可以使用 JavaScript! 我们将选择按钮类 (.btn-toggle),添加一个点击监听器,然后将暗黑主题类 (.dark-theme) 添加到 body 元素的类列表中。 由于级联和特异性,这实际上会覆盖我们设置的所有“亮色”,

以下是完整的代码在实际操作中的演示。 点击切换按钮以在暗黑模式和亮色模式之间切换。

使用单独的样式表

我们无需将所有样式保留在一个样式表中,而是可以为每个主题切换样式表。 这假设您已经准备好了完整的样式表。

例如,一个默认的亮色主题,比如light-theme.css

/* light-theme.css */


body {
  color: #222;
  background: #fff;
}
a {
  color: #0033cc;
}

然后,我们创建暗黑主题的样式,并将它们保存到一个我们称之为dark-theme.css的单独样式表中。

/* dark-theme.css */


body {
  color: #eee;
  background: #121212;
}
body a {
  color: #809fff;
}

这为我们提供了两个独立的样式表——每个主题一个——我们可以将其链接到 HTML 的<head>部分中。 让我们先链接亮色样式,因为我们将其称为默认样式。

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Light theme stylesheet -->
  <link href="light-theme.css" rel="stylesheet" id="theme-link">
</head>


<!-- etc. -->


</html>

我们使用一个#theme-link ID,我们可以使用 JavaScript 选择它,再次在亮色模式和暗黑模式之间切换。 只是这次,我们切换的是文件而不是类。

// Select the button
const btn = document.querySelector(".btn-toggle");
// Select the stylesheet <link>
const theme = document.querySelector("#theme-link");

// Listen for a click on the button
btn.addEventListener("click", function() {
  // If the current URL contains "ligh-theme.css"
  if (theme.getAttribute("href") == "light-theme.css") {
    // ... then switch it to "dark-theme.css"
    theme.href = "dark-theme.css";
  // Otherwise...
  } else {
    // ... switch it to "light-theme.css"
    theme.href = "light-theme.css";
  }
});

使用自定义属性

我们也可以利用 CSS 自定义属性的强大功能来创建暗黑主题! 它可以帮助我们避免为每个主题编写单独的样式规则集,从而使编写样式变得更快,并且如果需要更改主题,也更容易进行更改。

我们仍然可以选择切换 body 类,并使用该类重新设置自定义属性

// Select the button
const btn = document.querySelector(".btn-toggle");


// Listen for a click on the button
btn.addEventListener("click", function() {
  // Then toggle (add/remove) the .dark-theme class to the body
  document.body.classList.toggle("dark-theme");
});

首先,让我们将默认亮色值定义为 body 元素上的自定义属性

body {
  --text-color: #222;
  --bkg-color: #fff;
  --anchor-color: #0033cc;
}

现在,我们可以像在第一种方法中一样,在一个.dark-theme body 类上重新定义这些值

body.dark-theme {
  --text-color: #eee;
  --bkg-color: #121212;
  --anchor-color: #809fff;
}

以下是我们使用自定义属性的 body 和链接元素的规则集

body {
  color: var(--text-color);
  background: var(--bkg-color);
}
a {
  color: var(--anchor-color);
}

我们也可以在文档的:root中定义我们的自定义属性。 这完全合法,而且 甚至是一种常见的做法。 在这种情况下,所有默认主题样式定义都将进入:root { },而所有暗黑主题属性都将进入:root.dark-mode { }

使用服务器端脚本

如果我们正在使用服务器端语言,例如 PHP,那么我们可以使用它而不是 JavaScript。 如果您更喜欢直接在标记中工作,这是一种很好的方法。

<?php
$themeClass = '';
if (isset($_GET['theme']) && $_GET['theme'] == 'dark') {
  $themeClass = 'dark-theme';
}


$themeToggle = ($themeClass == 'dark-theme') ? 'light' : 'dark';
?>
<!DOCTYPE html>
<html lang="en">
<!-- etc. -->
<body class="<?php echo $themeClass; ?>">
  <a href="?theme=<?php echo $themeToggle; ?>">Toggle Dark Mode</a>
  <!-- etc. -->
</body>
</html>

我们可以让用户发送一个GETPOST请求。 然后,我们让我们的代码(在本例中是 PHP)在页面重新加载时应用相应的 body 类。 出于演示目的,我正在使用GET请求(URL 参数)。

当然,我们也可以像在第二种方法中一样交换样式表。

<?php
$themeStyleSheet = 'light-theme.css';
if (isset($_GET['theme']) && $_GET['theme'] == 'dark') {
  $themeStyleSheet = 'dark-theme.css';
}


$themeToggle = ($themeStyleSheet == 'dark-theme.css') ? 'light' : 'dark';
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <!-- etc. -->
  <link href="<?php echo $themeStyleSheet; ?>" rel="stylesheet">
</head>


<body>
  <a href="?theme=<?php echo $themeToggle; ?>">Toggle Dark Mode</a>
  <!-- etc. -->
</body>
</html>

这种方法有一个明显的缺点:页面需要刷新才能切换。 但是,这种服务器端解决方案对于在页面重新加载时保持用户主题选择非常有用,正如我们将在后面看到的那样。


应该选择哪种方法?

“正确”的方法取决于您的项目的具体要求。 例如,如果您正在进行一个大型项目,那么您可能可以选择 CSS 属性来帮助管理一个大型代码库。 另一方面,如果您的项目需要支持旧版浏览器,那么将需要使用其他方法。

此外,并没有规定我们只能使用一种方法。 有时候,多种方法的组合将是最有效的方法。 甚至可能存在我们尚未讨论的其他可能方法。


操作系统级别的暗黑模式

到目前为止,我们一直在使用按钮在亮色模式和暗黑模式之间切换,但我们可以简单地让用户的操作系统为我们完成这项工作。 例如,许多操作系统允许用户直接在系统设置中选择亮色和暗黑主题。

MacOS 系统偏好设置中的“通用”设置

纯 CSS

细节

幸运的是,CSS 有一个prefers-color-scheme媒体查询,可以用来检测用户的系统颜色方案偏好。 它可以有三个可能的值:无偏好、亮色和暗黑。 在 MDN 上了解更多信息 MDN

@media (prefers-color-scheme: dark) {
  /* Dark theme styles go here */
}


@media (prefers-color-scheme: light) {
  /* Light theme styles go here */
}

要使用它,我们可以将深色主题样式放在媒体查询中。

@media (prefers-color-scheme: dark) {
  body {
    color: #eee;
    background: #121212;
  }


  a {
    color: #809fff;
  }
}

现在,如果用户从系统设置中启用了深色模式,他们将默认获得深色模式样式。我们无需使用 JavaScript 或服务器端脚本来决定使用哪种模式。实际上,我们甚至不再需要按钮了!

JavaScript

细节

我们可以使用 JavaScript 来检测用户的首选配色方案。这很像我们使用过的第一种方法,只是我们使用 matchedMedia() 来检测用户的偏好。

const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');nnif (prefersDarkScheme.matches) {n  document.body.classList.add('dark-theme');n} else {n  document.body.classList.remove('dark-theme');n}

使用 JavaScript 的缺点是:由于 JavaScript 在 CSS 之后执行,因此可能会出现浅色主题的快速闪烁。这可能会被误认为是 bug。

当然,我们可以像在第二种方法中那样交换样式表。这次,我们链接了两个样式表,并使用媒体查询来确定应用哪一个。

覆盖操作系统设置

我们刚刚了解了如何考虑用户的系统范围内的配色方案偏好。但是,如果用户想覆盖他们在网站上的系统偏好怎么办? 仅仅因为用户喜欢他们操作系统的深色模式,并不一定意味着他们也喜欢网站上的深色模式。因此,提供一种方法来手动覆盖深色模式,即使系统设置也如此,是一个好主意。

查看代码

让我们使用 CSS 自定义属性方法来演示如何做到这一点。思路是像以前一样定义两种主题的自定义属性,将深色样式包装在 prefers-color-scheme 媒体查询中,然后在其中定义一个 .light-theme 类,如果用户想在两种模式之间切换,可以使用该类来覆盖深色模式属性。

/* Default colors */
body {
  --text-color: #222;
  --bkg-color: #fff;
}
/* Dark theme colors */
body.dark-theme {
  --text-color: #eee;
  --bkg-color: #121212;
}

/* Styles for users who prefer dark mode at the OS level */
@media (prefers-color-scheme: dark) {
  /* defaults to dark theme */
  body { 
    --text-color: #eee;
    --bkg-color: #121212;
  }
  /* Override dark mode with light mode styles if the user decides to swap */
  body.light-theme {
    --text-color: #222;
    --bkg-color: #fff;
  }
}

现在我们可以回到我们可靠的按钮来切换浅色和深色主题。这样,我们默认情况下尊重操作系统颜色偏好,允许用户手动切换主题。

// Listen for a click on the button 
btn.addEventListener("click", function() {
  // If the OS is set to dark mode...
  if (prefersDarkScheme.matches) {
    // ...then apply the .light-theme class to override those styles
    document.body.classList.toggle("light-theme");
    // Otherwise...
  } else {
    // ...apply the .dark-theme class to override the default light styles
    document.body.classList.toggle("dark-theme");
  }
});

浏览器支持

prefers-color-scheme 媒体查询功能得到了主要浏览器的支持,包括 Chrome 76+、Firefox 67+、Chrome Android 76+、Safari 12.5+(iOS 上为 13+)和三星互联网浏览器。它不支持 IE。

这是一个很有希望的支持量!Can I Use 估计用户覆盖率为 80.85%。

目前支持深色模式的操作系统包括 MacOS(Mojave 或更高版本)、iOS(13.0+)、Windows(10+)和 Android(10+)。


存储用户的偏好

到目前为止,我们所看到的内容肯定做到了它的宣传:根据操作系统偏好或按钮点击来切换主题。这很好,但当用户访问网站上的另一个页面或重新加载当前页面时,它不会延续。

我们需要保存用户的选择,以便在整个网站和后续访问中一致地应用它。为此,我们可以在主题切换时将用户的选择保存到 localStorage 中。Cookie 也非常适合这项工作。

让我们看看这两种方法。

使用 localStorage

我们有一个脚本,当切换发生时,它将选定的主题保存到 localStorage 中。换句话说,当页面重新加载时,脚本从 localStorage 中获取选择并应用它。JavaScript 通常在 CSS 之后执行,因此这种方法容易出现“错误主题闪烁”(FOIT)

查看代码
// Select the button
const btn = document.querySelector(".btn-toggle");
// Select the theme preference from localStorage
const currentTheme = localStorage.getItem("theme");


// If the current theme in localStorage is "dark"...
if (currentTheme == "dark") {
  // ...then use the .dark-theme class
  document.body.classList.add("dark-theme");
}


// Listen for a click on the button 
btn.addEventListener("click", function() {
  // Toggle the .dark-theme class on each click
  document.body.classList.toggle("dark-theme");
  
  // Let's say the theme is equal to light
  let theme = "light";
  // If the body contains the .dark-theme class...
  if (document.body.classList.contains("dark-theme")) {
    // ...then let's make the theme dark
    theme = "dark";
  }
  // Then save the choice in localStorage
  localStorage.setItem("theme", theme);
});

使用 PHP 和 Cookie

为了避免 FLIC,我们可以使用 PHP 之类的服务器端脚本。我们不会将用户的主题偏好保存在 localStorage 中,而是会从 JavaScript 创建一个 cookie 并将其保存到那里。但同样,这可能只有在您已经使用服务器端语言时才可行。

查看代码
// Select the button
const btn = document.querySelector(".btn-toggle");


// Listen for a click on the button 
btn.addEventListener("click", function() {
  // Toggle the .dark-theme class on the body
  document.body.classList.toggle("dark-theme");
  
  // Let's say the theme is equal to light
  let theme = "light";
  // If the body contains the .dark-theme class...
  if (document.body.classList.contains("dark-theme")) {
    // ...then let's make the theme dark
    theme = "dark";
  }
  // Then save the choice in a cookie
  document.cookie = "theme=" + theme;
});

我们现在可以检查该 cookie 是否存在,并通过将适当的类应用于 <body> 标签来加载相应的主题。

<?php
$themeClass = '';
if (!empty($_COOKIE['theme']) && $_COOKIE['theme'] == 'dark') {
  $themeClass = 'dark-theme';
}
?>


<!DOCTYPE html>
<html lang="en">
<!-- etc. -->
<body class="<?php echo $themeClass; ?>">
<!-- etc. -->
</body>
</html>

以下是如何使用单独样式表方法来实现。

<?php
$themeStyleSheet = 'light-theme.css';
if (!empty($_COOKIE['theme']) && $_COOKIE['theme'] == 'dark') {
  $themeStyleSheet = 'dark-theme.css';
}
?>


<!DOCTYPE html>
<html lang="en">
<head>
  <!-- etc. -->
  <link href="<?php echo $themeStyleSheet; ?>" rel="stylesheet" id="theme-link">
</head>
<!-- etc. -->

如果您的网站有用户帐户 - 比如登录和管理个人资料信息的地方 - 那里也是保存主题偏好的好地方。将其发送到存储用户帐户详细信息的数据库。然后,当用户登录时,从数据库中获取主题,并使用 PHP(或任何服务器端脚本)将其应用到页面。

有多种方法可以做到这一点。在本例中,我在登录时从数据库中获取用户的主题偏好,并将其保存在一个会话变量中。

<?php
// Login action
if (!empty($_POST['login'])) {
  // etc.


  // If the uuser is authenticated...
  if ($loginSuccess) {
    // ... save their theme preference to a session variable
    $_SESSION['user_theme'] = $userData['theme'];
  }
}


// Pick the session variable first if it's set; otherwise pick the cookie
$themeChoice = $_SESSION['user_theme'] ?? $_COOKIE['theme'] ?? null;
$themeClass = '';
if ($themeChoice == 'dark') {
  $themeClass = 'dark-theme';
}
?>


<!DOCTYPE html>
<html lang="en">
<!-- etc. -->
<body class="<?php echo $themeClass; ?>">
<!-- etc. -->
</body>
</html>

我正在使用 PHP 的 null 合并运算符??)来决定从哪里获取主题偏好:从会话还是从 cookie 中。如果用户已登录,则使用会话变量的值,而不是 cookie 的值。如果用户未登录或已注销,则使用 cookie 的值。


处理用户代理样式

为了告知浏览器 UA 样式表系统颜色方案偏好,并告诉它页面中支持哪些颜色方案,我们可以使用 color-scheme 元标签。

例如,假设页面应该支持“深色”和“浅色”两种主题。我们可以将它们都作为值放在元标签中,用空格隔开。如果我们只希望支持“浅色”主题,那么我们只需要使用“浅色”作为值即可。这在 CSSWG GitHub 问题 中进行了讨论,最初是在这里提出的。

<meta name="color-scheme" content="dark light">

当添加此元标签时,浏览器会在渲染页面中 UA 控制的元素(如 <button>)时考虑用户的颜色方案偏好。它会根据用户的偏好渲染根背景、表单控件和拼写检查功能(以及任何其他 UA 控制的样式)的颜色。

来源

虽然主题在很大程度上是手动设置样式的(这会覆盖 UA 样式),但告知浏览器支持的主题有助于避免出现即使是最轻微的潜在 FOIT 情况。对于 HTML 已经渲染但 CSS 仍在等待加载的那些情况,这是正确的。

我们也可以在 CSS 中设置它

:root {
  color-scheme: light dark; /* both supported */
}
通过 Jim Nielsen

在撰写本文时,color-scheme 属性 缺乏广泛的浏览器支持,尽管 Safari 和 Chrome 都支持它。


结合所有内容!

让我们将所有内容结合起来,创建一个工作演示,它

  1. 根据系统偏好自动加载深色或浅色主题
  2. 允许用户手动覆盖其系统偏好
  3. 在页面重新加载时保留用户首选的主题

使用 JavaScript 和 Local Storage

// Select the button
const btn = document.querySelector(".btn-toggle");
// Check for dark mode preference at the OS level
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");


// Get the user's theme preference from local storage, if it's available
const currentTheme = localStorage.getItem("theme");
// If the user's preference in localStorage is dark...
if (currentTheme == "dark") {
  // ...let's toggle the .dark-theme class on the body
  document.body.classList.toggle("dark-mode");
// Otherwise, if the user's preference in localStorage is light...
} else if (currentTheme == "light") {
  // ...let's toggle the .light-theme class on the body
  document.body.classList.toggle("light-mode");
}


// Listen for a click on the button 
btn.addEventListener("click", function() {
  // If the user's OS setting is dark and matches our .dark-mode class...
  if (prefersDarkScheme.matches) {
    // ...then toggle the light mode class
    document.body.classList.toggle("light-mode");
    // ...but use .dark-mode if the .light-mode class is already on the body,
    var theme = document.body.classList.contains("light-mode") ? "light" : "dark";
  } else {
    // Otherwise, let's do the same thing, but for .dark-mode
    document.body.classList.toggle("dark-mode");
    var theme = document.body.classList.contains("dark-mode") ? "dark" : "light";
  }
  // Finally, let's save the current preference to localStorage to keep using it
  localStorage.setItem("theme", theme);
});

使用 PHP 和 Cookie

<?php
$themeClass = '';
if (!empty($_COOKIE['theme'])) {
  if ($_COOKIE['theme'] == 'dark') {
    $themeClass = 'dark-theme';
  } else if ($_COOKIE['theme'] == 'light') {
    $themeClass = 'light-theme';
  }  
}
?>


<!DOCTYPE html>
<html lang="en">
<!-- etc. -->
<body class="<?php echo $themeClass; ?>">
<!-- etc. -->
<script>
  const btn = document.querySelector(".btn-toggle");
  const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
  
  btn.addEventListener("click", function() {
    if (prefersDarkScheme.matches) {
      document.body.classList.toggle("light-mode");
      var theme = document.body.classList.contains("light-mode") ? "light" : "dark";
    } else {
      document.body.classList.toggle("dark-mode");
      var theme = document.body.classList.contains("dark-mode") ? "dark" : "light";
    }
    document.cookie = "theme=" + theme;
  });
</script>
</body>
</html>

设计注意事项

我经常听到人们说,实现深色模式比设计深色模式更容易。虽然我不会妄加评论,但让我们来看看设计深色主题的一些注意事项。

您已经知道基本任务:将较浅的颜色值替换为较深的颜色值,反之亦然。但是,有一些 UI 元素和增强功能更加细致,需要更多关注。让我们来看看这些。

深色模式图像

一个好的规则是稍微降低图像的亮度和对比度,这样在深色背景下观看时会更舒适。在超深色背景上放置超亮图像可能会令人不适,而调暗图像可以减少一些强烈的对比度。

CSS 的 filter() 函数完全能够为我们处理这个问题

/* Apply the filter directly on the body tag */
body.dark-theme img {
  filter: brightness(.8) contrast(1.2);
}


/* Or apply it via media query */
@media (prefers-color-scheme: dark) {
  img {
    filter: brightness(.8) contrast(1.2);
  }
}

我们可以在标记中直接使用 <picture> 元素来加载图像的不同版本,从而实现类似的效果。

<picture>
  <!-- Use this image if the user's OS setting is light or unset -->
  <source srcset="photo-light.png" media="(prefers-color-scheme: light) or (prefers-color-scheme: no-preference)">
  <!-- Use this image if the user's OS setting is dark -->
  <source srcset="photo-dark.png" media="(prefers-color-scheme: dark)">
</picture>

这样做的缺点是,我们需要提供两个文件,而使用 CSS 时只需要处理一个文件。这也不能完全解决用户在网站上切换颜色主题的问题。

深色模式阴影

深色模式阴影很棘手。如果我们只是用浅色反转深色阴影,那么我们会得到一个奇怪的东西,即深色背景上有一个浅色阴影……这不好看。

在深色模式中使用深色阴影是可能的,但背景颜色必须“足够浅”(比如深灰色),才能提供足够的对比度,以便在背景上看到阴影。

使用不透明度来传达深度,不透明度较高的区域具有较低的深度。也就是说,具有较高海拔的元素应该具有比“更靠近”背景的元素更低的不透明度。

不同的颜色阴影会产生不同的“深度”感知。

深色模式排版

这里的诀窍很像图像:我们必须平衡对比度。使用太重的字体会导致刺眼的文本,让我们想要远离屏幕。使用太轻的字体会导致我们眯起眼睛,同时向屏幕靠近以看得更清楚。

平衡点介于两者之间。Robin 有一篇很好的文章,他建议使用一些简单的 CSS 代码,这对于可读性有很大帮助。

深色模式图标

图标属于“棘手”类别,因为它们有点介于文本和图像之间。但是,如果我们使用 SVG 图标,我们可以使用 CSS 更改填充。另一方面,如果我们使用字体图标,我们可以简单地更改颜色属性。

/* SVG icon */
body.dark-theme svg.icon path {
  fill: #efefef;
}
/* Font icon (using Font Awesome as an example) */
body.dark-theme .fa {
  color: #efefef;
}

文本的大多数设计注意事项通常也适用于图标。例如,我们应该避免使用纯白色和粗重的轮廓。

深色模式颜色

纯白色文本在纯黑色背景上看起来会很刺眼。这里的诀窍是使用淡白色作为文本,使用淡黑色作为背景。Material Design 指南 例如建议将 #121212 用于背景。

深色模式调色板

我们已经看到了使用淡白色和淡黑色会对文本和图像造成的影响。让我们进一步探讨一些关于如何开发完整调色板的提示。

大多数事情归结为一点:对比度。这就是为什么在确定任何颜色之前,第一个提示是将想法通过对比度检查器来运行,以确保颜色比率符合 WCAG 的至少 AA 等级指南,即 4.5:1 的对比度比率

这意味着在使用深色模式设计时,非饱和色是我们的朋友。它们有助于防止过于明亮的图像,并且仍然为我们提供了足够的空间来创建有效的对比度比率。

接下来,请记住,强调色是用来增强的。它们可能比深色主题背景色更亮,因此将它们用作主色或大型容器的背景色,就像明亮的图像或浓重的白色文本一样,会让人不适,并且对眼睛有压力。

如果对比度是我们试图取得的平衡,那么请记住,深色模式不仅仅是黑色和灰色。深蓝色背景配淡黄色文本怎么样?或者深棕色配米色?那里有整个(并且不断增长)的颜色频谱,我们可以利用它的任何部分来激发创造力。

一些深色而不使用全黑的颜色的例子

#232B32

#152028

#202945

Material Design 关于深色模式的指南 是深色模式设计最佳实践的实用资源。它绝对值得一读,可以了解更多需要记住的提示。

深色模式在现实中的应用

YouTube 使用 CSS 变量技术。他们在 html 选择器下定义了所有颜色变量,而深色模式颜色则在 html:not(.style-scope)[dark] 下定义。启用深色模式时,YouTube 会在 <html> 标签中添加 dark="true" 属性。这就是他们用来覆盖 HTML 中定义的变量的方法。

YouTube 在切换到深色模式时,会在 <html> 标签中添加 dark=true 属性。

在现实中,CSS 自定义属性方法似乎最受欢迎。Dropbox Paper、Slack 和 Facebook 都在使用它。

Simplenote 使用类交换方法,所有浅色样式规则都是 .theme-light 父类的后代,所有深色样式都属于 .theme-dark 类。当主题切换时,相应的类将应用于 <body> 标签。

Simplenote 使用两个类:.light-theme.dark-theme 来设置主题样式。

Twitter 更进一步,提供了多种主题可供选择:“默认”、“昏暗”和“熄灯”。“昏暗”选项使用深蓝色作为背景色。与使用纯黑色的“熄灯”相比。

Twitter 提供三种主题可供选择。

深色模式还是不深色模式?这是一个问题。

双方都有充分的理由。其中一些原因甚至超出了用户体验的范围,包括时间、预算和资源等方面。

在考虑为什么您可能不想实现深色模式的同时,以下是一些您可能想要使用深色模式的原因。

  • 它很酷,很流行(虽然这不能作为唯一的理由)。
  • 它通过支持对刺眼的明亮主题敏感的用户,来增强可访问性。
  • 它允许用户决定最舒适的消费内容方式,同时为我们提供了一种方法来控制事物的视觉效果。请记住,我们想要击败阅读模式按钮
  • 它有助于延长配备 OLED 屏幕的设备的电池续航时间,因为更明亮的颜色会消耗更多能量。
  • 它非常受欢迎,而且似乎不会消失。您喜欢深色模式的用户(比如我!)可能会期望您的网站也有深色模式。最好做好准备。