在現代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元素進行暗色和亮色主題的定制,當然官方還支持多個自定義主題,有興趣的話可以看官方文檔。