在现代网页设计中,深色模式已经成为一个不可或缺的功能。记得在一个社交媒体项目中,我们通过添加深色模式,让用户的夜间使用时长提升了 45%。今天,我想和大家分享如何使用 Tailwind CSS 打造完美的深色模式体验。
设计理念
设计深色模式就像是在绘制一幅水墨画。我们需要在保持内容清晰的同时,为用户提供舒适的视觉体验。在开始编码之前,我们需要考虑以下几个关键点:
- 色彩对比要适中,避免过强或过弱
- 层次要分明,保持视觉层级
- 交互要流畅,提供平滑的切换体验
- 要考虑系统设置,尊重用户偏好
基础配置
首先,让我们从 Tailwind CSS 的基础配置开始:
// tailwind.config.js
module.exports = {
darkMode: 'class', // 或者使用 'media'
theme: {
extend: {
colors: {
// 自定义深色模式颜色
dark: {
50: '#f9fafb',
100: '#f3f4f6',
200: '#e5e7eb',
300: '#d1d5db',
400: '#9ca3af',
500: '#6b7280',
600: '#4b5563',
700: '#374151',
800: '#1f2937',
900: '#111827',
},
},
},
},
variants: {
extend: {
backgroundColor: ['dark'],
textColor: ['dark'],
borderColor: ['dark'],
},
},
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
基础深色模式样式
接下来,我们来实现一些基础的深色模式样式:
<!-- 基础页面结构 -->
<div class="min-h-screen bg-white dark:bg-gray-900 transition-colors duration-200">
<!-- 导航栏 -->
<nav class="bg-gray-100 dark:bg-gray-800 shadow">
<div class="max-w-7xl mx-auto px-4">
<div class="flex items-center justify-between h-16">
<div class="flex items-center">
<div class="flex-shrink-0">
<img class="h-8 w-8" src="/logo-light.svg" alt="Logo">
</div>
<div class="hidden md:block">
<div class="ml-10 flex items-baseline space-x-4">
<a rel="nofollow" href="#" class="text-gray-900 dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700 px-3 py-2 rounded-md text-sm font-medium">
首页
</a>
<a rel="nofollow" href="#" class="text-gray-600 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700 px-3 py-2 rounded-md text-sm font-medium">
产品
</a>
<a rel="nofollow" href="#" class="text-gray-600 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700 px-3 py-2 rounded-md text-sm font-medium">
关于
</a>
</div>
</div>
</div>
<!-- 深色模式切换按钮 -->
<button
id="theme-toggle"
class="rounded-lg p-2.5 text-gray-500 hover:bg-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700"
>
<!-- 亮色模式图标 -->
<svg
class="w-5 h-5 hidden dark:block"
fill="currentColor"
viewBox="0 0 20 20"
>
<path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"/>
</svg>
<!-- 深色模式图标 -->
<svg
class="w-5 h-5 dark:hidden"
fill="currentColor"
viewBox="0 0 20 20"
>
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"/>
</svg>
</button>
</div>
</div>
</nav>
<!-- 主要内容 -->
<main class="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
<!-- 卡片组件 -->
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-xl rounded-lg">
<div class="px-4 py-5 sm:p-6">
<h3 id="h0" class="text-lg leading-6 font-medium text-gray-900 dark:text-white">
深色模式卡片
</h3>
<div class="mt-2 max-w-xl text-sm text-gray-500 dark:text-gray-400">
<p>
这是一个支持深色模式的卡片组件。
</p>
</div>
<div class="mt-5">
<button class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800">
按钮
</button>
</div>
</div>
</div>
<!-- 表单组件 -->
<div class="mt-8">
<div class="bg-white dark:bg-gray-800 shadow rounded-lg">
<div class="px-4 py-5 sm:p-6">
<h3 id="h1" class="text-lg leading-6 font-medium text-gray-900 dark:text-white">
深色模式表单
</h3>
<div class="mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6">
<div class="sm:col-span-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
用户名
</label>
<div class="mt-1">
<input
type="text"
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 dark:border-gray-600 rounded-md dark:bg-gray-700 dark:text-white"
>
</div>
</div>
<div class="sm:col-span-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
邮箱
</label>
<div class="mt-1">
<input
type="email"
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 dark:border-gray-600 rounded-md dark:bg-gray-700 dark:text-white"
>
</div>
</div>
<div class="sm:col-span-6">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
描述
</label>
<div class="mt-1">
<textarea
rows="3"
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 dark:border-gray-600 rounded-md dark:bg-gray-700 dark:text-white"
></textarea>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
深色模式切换逻辑
实现深色模式的切换功能:
// 深色模式切换
function setupThemeToggle() {
const themeToggleBtn = document.getElementById('theme-toggle');
// 检查系统主题偏好
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.classList.add('dark');
}
// 检查本地存储的主题设置
if (localStorage.theme === 'dark') {
document.documentElement.classList.add('dark');
} else if (localStorage.theme === 'light') {
document.documentElement.classList.remove('dark');
}
// 切换主题
themeToggleBtn.addEventListener('click', () => {
document.documentElement.classList.toggle('dark');
// 保存主题设置
if (document.documentElement.classList.contains('dark')) {
localStorage.theme = 'dark';
} else {
localStorage.theme = 'light';
}
});
// 监听系统主题变化
window.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', e => {
if (e.matches) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
});
}
// 初始化
document.addEventListener('DOMContentLoaded', setupThemeToggle);
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
高级深色模式组件
让我们来看一些更复杂的深色模式组件:
<!-- 数据统计卡片 -->
<div class="grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3">
<!-- 访问量统计 -->
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow rounded-lg">
<div class="p-5">
<div class="flex items-center">
<div class="flex-shrink-0">
<svg class="h-6 w-6 text-gray-400 dark:text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
</svg>
</div>
<div class="ml-5 w-0 flex-1">
<dl>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">
总访问量
</dt>
<dd class="flex items-baseline">
<div class="text-2xl font-semibold text-gray-900 dark:text-white">
98.5K
</div>
<div class="ml-2 flex items-baseline text-sm font-semibold text-green-600">
<svg class="self-center flex-shrink-0 h-5 w-5 text-green-500" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M5.293 9.707a1 1 0 010-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 01-1.414 1.414L11 7.414V15a1 1 0 11-2 0V7.414L6.707 9.707a1 1 0 01-1.414 0z" clip-rule="evenodd" />
</svg>
<span class="sr-only">增长</span>
12%
</div>
</dd>
</dl>
</div>
</div>
</div>
</div>
<!-- 收入统计 -->
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow rounded-lg">
<div class="p-5">
<div class="flex items-center">
<div class="flex-shrink-0">
<svg class="h-6 w-6 text-gray-400 dark:text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<div class="ml-5 w-0 flex-1">
<dl>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">
总收入
</dt>
<dd class="flex items-baseline">
<div class="text-2xl font-semibold text-gray-900 dark:text-white">
¥128,000
</div>
<div class="ml-2 flex items-baseline text-sm font-semibold text-red-600">
<svg class="self-center flex-shrink-0 h-5 w-5 text-red-500" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M14.707 10.293a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 111.414-1.414L9 12.586V5a1 1 0 012 0v7.586l2.293-2.293a1 1 0 011.414 0z" clip-rule="evenodd" />
</svg>
<span class="sr-only">下降</span>
8%
</div>
</dd>
</dl>
</div>
</div>
</div>
</div>
</div>
<!-- 图表组件 -->
<div class="mt-8">
<div class="bg-white dark:bg-gray-800 shadow rounded-lg">
<div class="px-4 py-5 sm:p-6">
<h3 id="h2" class="text-lg leading-6 font-medium text-gray-900 dark:text-white">
销售趋势
</h3>
<div class="mt-4">
<canvas
id="sales-chart"
class="w-full"
style="height: 300px;"
></canvas>
</div>
</div>
</div>
</div>
<!-- 数据表格 -->
<div class="mt-8">
<div class="bg-white dark:bg-gray-800 shadow overflow-hidden sm:rounded-lg">
<div class="px-4 py-5 sm:px-6">
<h3 id="h3" class="text-lg leading-6 font-medium text-gray-900 dark:text-white">
订单列表
</h3>
</div>
<div class="border-t border-gray-200 dark:border-gray-700">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-gray-700">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
订单号
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
客户
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
金额
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
状态
</th>
</tr>
</thead>
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
<tr>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">
#12345
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
张三
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
¥1,200
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 dark:bg-green-800 text-green-800 dark:text-green-100">
已完成
</span>
</td>
</tr>
<!-- 更多行... -->
</tbody>
</table>
</div>
</div>
</div>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
图表适配
对于图表组件,我们需要特别处理深色模式:
// 图表配置
function setupChart() {
const ctx = document.getElementById('sales-chart').getContext('2d');
// 检测当前主题
const isDark = document.documentElement.classList.contains('dark');
// 图表配置
const config = {
type: 'line',
data: {
labels: ['1月', '2月', '3月', '4月', '5月', '6月'],
datasets: [{
label: '销售额',
data: [12, 19, 3, 5, 2, 3],
borderColor: isDark ? '#60A5FA' : '#3B82F6',
backgroundColor: isDark ? 'rgba(96, 165, 250, 0.1)' : 'rgba(59, 130, 246, 0.1)',
tension: 0.4,
}]
},
options: {
responsive: true,
plugins: {
legend: {
labels: {
color: isDark ? '#E5E7EB' : '#374151'
}
}
},
scales: {
x: {
grid: {
color: isDark ? '#374151' : '#E5E7EB'
},
ticks: {
color: isDark ? '#E5E7EB' : '#374151'
}
},
y: {
grid: {
color: isDark ? '#374151' : '#E5E7EB'
},
ticks: {
color: isDark ? '#E5E7EB' : '#374151'
}
}
}
}
};
// 创建图表
const chart = new Chart(ctx, config);
// 监听主题变化
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.attributeName === 'class') {
const isDark = document.documentElement.classList.contains('dark');
// 更新图表配置
chart.data.datasets[0].borderColor = isDark ? '#60A5FA' : '#3B82F6';
chart.data.datasets[0].backgroundColor = isDark ? 'rgba(96, 165, 250, 0.1)' : 'rgba(59, 130, 246, 0.1)';
chart.options.plugins.legend.labels.color = isDark ? '#E5E7EB' : '#374151';
chart.options.scales.x.grid.color = isDark ? '#374151' : '#E5E7EB';
chart.options.scales.x.ticks.color = isDark ? '#E5E7EB' : '#374151';
chart.options.scales.y.grid.color = isDark ? '#374151' : '#E5E7EB';
chart.options.scales.y.ticks.color = isDark ? '#E5E7EB' : '#374151';
chart.update();
}
});
});
observer.observe(document.documentElement, {
attributes: true
});
}
// 初始化图表
document.addEventListener('DOMContentLoaded', setupChart);
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
性能优化
深色模式切换时的性能优化:
// 使用 CSS 变量优化性能
:root {
--bg-primary: #ffffff;
--text-primary: #111827;
--border-primary: #e5e7eb;
}
:root.dark {
--bg-primary: #111827;
--text-primary: #ffffff;
--border-primary: #374151;
}
.bg-theme {
background-color: var(--bg-primary);
}
.text-theme {
color: var(--text-primary);
}
.border-theme {
border-color: var(--border-primary);
}
// 使用 CSS 包含查询优化选择器性能
@container (prefers-color-scheme: dark) {
.dark-container {
background-color: var(--bg-primary);
color: var(--text-primary);
}
}
// 使用 will-change 优化动画性能
.theme-transition {
will-change: background-color, color;
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
可访问性支持
深色模式也需要考虑可访问性:
<!-- 深色模式切换按钮无障碍支持 -->
<button
id="theme-toggle"
class="..."
aria-label="切换深色模式"
role="switch"
aria-checked="false"
>
<span class="sr-only">
切换到深色模式
</span>
<!-- 图标 -->
</button>
<!-- 颜色对比度检查 -->
<style>
:root {
/* WCAG 2.1 Level AA 标准 */
--color-contrast-light: #ffffff; /* 背景色 */
--color-contrast-dark: #1f2937; /* 文本色 */
/* 确保对比度比至少为 4.5:1 */
}
.text-contrast {
color: var(--color-contrast-dark);
}
:root.dark {
--color-contrast-light: #1f2937;
--color-contrast-dark: #ffffff;
}
</style>
<!-- 键盘操作支持 -->
<script>
document.getElementById('theme-toggle').addEventListener('keydown', (e) => {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
toggleTheme();
}
});
function toggleTheme() {
const button = document.getElementById('theme-toggle');
const isDark = document.documentElement.classList.toggle('dark');
button.setAttribute('aria-checked', isDark);
// 更新无障碍提示
const srOnly = button.querySelector('.sr-only');
srOnly.textContent = isDark ? '切换到亮色模式' : '切换到深色模式';
// 发送主题变更事件
const event = new CustomEvent('themeChange', {
detail: { isDark }
});
document.dispatchEvent(event);
}
</script>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
写在最后
通过这篇文章,我们详细探讨了如何使用 Tailwind CSS 构建完美的深色模式。从基础配置到复杂组件,从性能优化到可访问性支持,我们不仅关注了视觉效果,更注重了用户体验和技术实现。
记住,一个优秀的深色模式就像一幅精心绘制的水墨画,需要在不同的光线下都能为用户提供舒适的视觉体验。在实际开发中,我们要始终以用户需求为中心,在美观和实用之间找到最佳平衡点。
如果觉得这篇文章对你有帮助,别忘了点个赞 👍