在Vue或React项目中使用Tailwind CSS实现暗黑模式切换:从系统适配到手动控制
在现代Web开发中,暗黑模式(Dark Mode)已成为提升用户体验的重要功能。本文将带你使用
Tailwind CSS
在React项目(Vue项目类似)
中实现两种暗黑模式控制方式:
- 系统自动适配 - 根据用户设备偏好自动切换
- 手动切换 - 通过按钮让用户自由选择
一、项目准备
使用vite创建一个项目,vue
和react
都可以,我这里是react
npm create vite@latest
在项目中启用tailwindcss
npm install tailwindcss @tailwindcss/vite
在项目下的vite.config.ts
中添加tailwindcss
插件
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'// https://vite.dev/config/
export default defineConfig({plugins: [react(),tailwindcss(),],
})
在index.css
中引入tailwindcss,并在main.tsx中引入index.css
/* index.css */
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'createRoot(document.getElementById('root')!).render(<StrictMode><App /></StrictMode>,
)
接下来我们在App.tsx
中编写我们的暗黑模式切换代码
二、tailwindcss暗黑模式切换
2.1 prefers-color-scheme
控制暗黑模式
Tailwind 默认通过 prefers-color-scheme
CSS 媒体查询控制暗模式。意思是 它会根据用户的操作系统或浏览器设置自动应用暗模式或亮模式样式。
2.1.1 什么是 prefers-color-scheme
?
prefers-color-scheme
是一种 CSS 媒体查询,可以检测用户系统的外观偏好:
@media (prefers-color-scheme: dark) {/* 暗模式样式 */
}@media (prefers-color-scheme: light) {/* 亮模式样式 */
}
操作系统(如 macOS、Windows、iOS、Android)或浏览器如果启用了“暗模式”,那么 prefers-color-scheme: dark
条件会变为 true
。
2.1.2 Tailwind 如何利用 prefers-color-scheme
?
Tailwind 提供了一个 dark:
变体,可以根据是否处于暗模式应用不同的样式。
例子:
<h1 class="text-black dark:text-white">Hello</h1>
- 当用户系统是亮模式 → 显示黑色文字
- 当用户系统是暗模式 → 显示白色文字
Tailwind 默认启用的是基于 media
的暗模式,也就是:
// tailwind.config.js
module.exports = {darkMode: 'media', // 默认值,根据系统设置自动切换
}
2.2 用户自己控制暗黑模式切换
如果我们不想根据用户系统自动切换,而是希望 手动控制暗模式(例如通过按钮),可以在index.css
中这样设置:
@import "tailwindcss";
/* 代表用户通过通过类名控制暗黑模式 */
@custom-variant dark (&:where(.dark, .dark *));
然后在App.tsx
中写入代码就可以用按钮手动控制暗黑模式了,使用 JavaScript 动态添加或移除 dark
类名,就可以实现手动切换。
import React, { useState } from 'react'const App: React.FC = () => {const [darkmode, setDarkmode] = useState(false)return (<div className={darkmode ? 'dark' : ''}><button className='rounded px-4 py-4 bg-sky-200 mx-2 my-2 cursor-pointer' onClick={()=>setDarkmode(!darkmode)}>切换模式</button><div className="bg-white dark:bg-gray-800 rounded-lg px-6 py-8 ring shadow-xl ring-gray-900/5"><div><span className="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg"><svg className="h-6 w-6 stroke-white"></svg></span></div><h3 className="text-gray-900 dark:text-white mt-5 text-base font-medium tracking-tight ">Writes upside-down</h3><p className="text-gray-500 dark:text-gray-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></div>)
}export default App
当然,除了用类名控制还可以使用数据属性
手动控制暗黑模式。原理和用类名控制差不多,区别是一个是css类选择器
,一个是用css属性选择器
。
@import "tailwindcss";
/* 使用数据属性手动控制暗黑模式切换 */
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
<html data-theme="dark"><body><div class="bg-white dark:bg-black"><!-- ... --></div></body>
</html>
总结:只要我们在项目中的顶层Dom元素
中动态控制类名(或属性名)
,就可以在整个页面精细的对每个Dom元素进行暗色和亮色主题的定制,当然官方还支持多个自定义主题,有兴趣的话可以看官方文档。