1. 核心概念
  2. 夜间模式

基本用法

既然夜间模式是许多操作系统的一流功能,设计网站的深色版本以配合默认设计变得越来越普遍。

¥Now that dark mode is a first-class feature of many operating systems, it’s becoming more and more common to design a dark version of your website to go along with the default design.

为了尽可能简化此操作,Tailwind 包含一个 dark 变体,可让你在启用夜间模式时以不同方式设置网站样式:

¥To make this as easy as possible, Tailwind includes a dark variant that lets you style your site differently when dark mode is enabled:

Light mode

Writes Upside-Down

The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.

Dark mode

Writes Upside-Down

The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.

<div class="bg-white dark:bg-slate-800 rounded-lg px-6 py-8 ring-1 ring-slate-900/5 shadow-xl">
  <div>
    <span class="inline-flex items-center justify-center p-2 bg-indigo-500 rounded-md shadow-lg">
      <svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true"><!-- ... --></svg>
    </span>
  </div>
  <h3 class="text-slate-900 dark:text-white mt-5 text-base font-medium tracking-tight">Writes Upside-Down</h3>
  <p class="text-slate-500 dark:text-slate-400 mt-2 text-sm">
    The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.
  </p>
</div>

默认情况下,这使用 prefers-color-scheme CSS 媒体功能,但你也可以使用 ‘selector’ 策略 构建支持手动切换夜间模式的站点。

¥By default this uses the prefers-color-scheme CSS media feature, but you can also build sites that support toggling dark mode manually using the ‘selector’ strategy.


手动切换夜间模式

¥Toggling dark mode manually

如果你想支持手动切换夜间模式而不是依赖于操作系统偏好,请使用 selector 策略而不是 media 策略:

¥If you want to support toggling dark mode manually instead of relying on the operating system preference, use the selector strategy instead of the media strategy:

selector 策略取代了 Tailwind CSS v3.4.1 中的 class 策略。

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: 'selector',
  // ...
}

现在,不再是基于 prefers-color-scheme 应用 dark:{class} 类,而是只要 dark 类出现在 HTML 树中较早的位置,就会应用它们。

¥Now instead of dark:{class} classes being applied based on prefers-color-scheme, they will be applied whenever the dark class is present earlier in the HTML tree.

<!-- Dark mode not enabled -->
<html>
<body>
  <!-- Will be white -->
  <div class="bg-white dark:bg-black">
    <!-- ... -->
  </div>
</body>
</html>

<!-- Dark mode enabled -->
<html class="dark">
<body>
  <!-- Will be black -->
  <div class="bg-white dark:bg-black">
    <!-- ... -->
  </div>
</body>
</html>

如果你在 Tailwind 配置中设置了 a prefix,请务必将其添加到 dark 类中。例如,如果你的前缀为 tw-,则需要使用 tw-dark 类来启用夜间模式。

¥If you’ve set a prefix in your Tailwind config, be sure to add that to the dark class. For example, if you have a prefix of tw-, you’ll need to use the tw-dark class to enable dark mode.

如何将 dark 类添加到 html 元素取决于你,但常见的方法是使用一些 JavaScript 从某处(如 localStorage)读取首选项并相应地更新 DOM。

¥How you add the dark class to the html element is up to you, but a common approach is to use a bit of JavaScript that reads a preference from somewhere (like localStorage) and updates the DOM accordingly.

自定义选择器

¥Customizing the selector

一些框架(如 NativeScript)有自己的方法来启用夜间模式,并在夜间模式处于活动状态时添加不同的类名。

¥Some frameworks (like NativeScript) have their own approach to enabling dark mode and add a different class name when dark mode is active.

你可以通过将 darkMode 设置为数组并将自定义选择器作为第二项来自定义夜间模式选择器:

¥You can customize the dark mode selector by setting darkMode to an array with your custom selector as the second item:

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: ['selector', '[data-mode="dark"]'],
  // ...
}

Tailwind 将自动使用 :where() 伪类封装你的自定义夜间模式选择器,以确保特异性与使用 media 策略时相同:

¥Tailwind will automatically wrap your custom dark mode selector with the :where() pseudo-class to make sure the specificity is the same as it would be when using the media strategy:

.dark\:underline:where([data-mode="dark"], [data-mode="dark"] *){
  text-decoration-line: underline
}

支持系统偏好和手动选择

¥Supporting system preference and manual selection

selector 策略可用于支持用户的系统偏好或使用 window.matchMedia() API 手动选择的模式。

¥The selector strategy can be used to support both the user’s system preference or a manually selected mode by using the window.matchMedia() API.

这是一个简单的示例,说明如何支持亮模式、夜间模式以及尊重操作系统首选项:

¥Here’s a simple example of how you can support light mode, dark mode, as well as respecting the operating system preference:

spaghetti.js
// On page load or when changing themes, best to add inline in `head` to avoid FOUC
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
  document.documentElement.classList.add('dark')
} else {
  document.documentElement.classList.remove('dark')
}

// Whenever the user explicitly chooses light mode
localStorage.theme = 'light'

// Whenever the user explicitly chooses dark mode
localStorage.theme = 'dark'

// Whenever the user explicitly chooses to respect the OS preference
localStorage.removeItem('theme')

同样,你可以按照自己喜欢的方式进行管理,甚至可以将首选项服务器端存储在数据库中并在服务器上渲染该类 - 这完全取决于你。

¥Again you can manage this however you like, even storing the preference server-side in a database and rendering the class on the server — it’s totally up to you.

覆盖黑暗变体

¥Overriding the dark variant

如果你想将 Tailwind 的内置深色变体替换为你自己的自定义变体,你可以使用 variant 夜间模式策略来实现:

¥If you’d like to replace Tailwind’s built-in dark variant with your own custom variant, you can do so using the variant dark mode strategy:

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: ['variant', '&:not(.light *)'],
  // ...
}

使用此策略时,Tailwind 不会以任何方式修改提供的选择器,因此请注意它的特殊性并考虑使用 :where() 伪类以确保它与其他工具具有相同的特殊性。

¥When using this strategy Tailwind will not modify the provided selector in any way, so be mindful of it’s specificity and consider using the :where() pseudo-class to ensure it has the same specificity as other utilities.

使用多个选择器

¥Using multiple selectors

如果你有多个应启用夜间模式的场景,你可以通过提供数组来指定所有场景:

¥If you have multiple scenarios where dark mode should be enabled, you can specify all of them by providing an array:

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: ['variant', [
    '@media (prefers-color-scheme: dark) { &:not(.light *) }',
    '&:is(.dark *)',
  ]],
  // ...
}