深色 / 浅色主题
本页说明主题系统的工作方式,包括三档模式、实现原理、卡片风格预设与微交互动画开关,以及深色模式下的特别行为。
主题系统由 ThemeContext(src/context/ThemeContext.jsx)驱动,导航栏右侧的 ThemeToggle 提供三个并列按钮:☀ 浅色、🌙 深色、🖥 跟随系统,点击任一按钮即切换到对应模式。
三档模式
三种模式的行为如下表所示:
| 模式 | 行为 |
|---|---|
| 浅色 | 强制浅色配色(colors.light) |
| 深色 | 强制深色配色(colors.dark) |
| 跟随系统(默认) | 根据操作系统的 prefers-color-scheme 自动选择;系统切换时页面实时跟随 |
选择结果保存在 localStorage(键 keqing-theme,值为 'light' | 'dark' | 'system'),下次访问自动恢复上次的选择。
实现原理
主题切换分三步实现:
- Tailwind 使用
darkMode: 'class'策略:深色模式下给<html>加.darkclass theme.config.js的colors.light/colors.dark由 Vite 插件生成两套 CSS 变量:css:root { --page-bg: #efe6f3; --text-primary: #1d1d1f; /* ... */ } .dark { --page-bg: #08081a; --text-primary: #f0f0f5; /* ... */ }- 切换主题只需增删
.darkclass,所有var(--xxx)引用即自动换色——一次 DOM 操作即可完成全站配色切换,组件无需重新渲染
跟随系统模式通过 matchMedia('(prefers-color-scheme: dark)') 监听系统变化,实时增删 .dark。
主题预设(卡片风格)
theme.config.js 的 preset 字段用于切换卡片视觉风格,与浅色 / 深色模式是两个独立维度,可任意组合:
| 预设 | 说明 |
|---|---|
'liquid-glass'(默认) | 液态玻璃:高光、反射、边缘光感 |
'frosted-glass' | 简约毛玻璃 |
'opaque' | 不透明实色卡片 |
'minimal' | 极简扁平 |
预设值在主题应用时写入 <html data-theme-preset="...">,基础液态玻璃样式在 src/styles/LiquidGlass.css,各预设(frosted-glass / opaque / minimal)的覆盖规则写在 src/index.css 末尾——切换预设无需修改任何组件代码。详见 主题配置。
微交互动画开关
theme.config.js → effects.animations 中每个动画都有独立开关。ThemeContext 在主题应用时会检查开关状态,关闭项会在 <html> 上设置对应的 data-disable-* 属性,CSS 检测到该属性即跳过对应动画。各开关与对应属性的关系如下表所示:
| 配置项 | 关闭时生成的属性 | 影响范围 |
|---|---|---|
buttonGlow.status = 'disable' | data-disable-button-glow | 所有按钮的悬停发光 / 上浮 |
cardHover.status = 'disable' | data-disable-card-hover | 卡片悬停上浮 |
iconHover.status = 'disable' | data-disable-icon-hover | 图标悬停缩放旋转 |
linkGlow.status = 'disable' | data-disable-link-glow | 链接光带滑入 |
musicVisualizer.status = 'disable' | data-disable-music-visualizer | 播放器律动条 |
pageEnter 进入动画没有 data 属性机制,由 HomePage 直接根据开关决定是否加动画 class。
深色模式下的特别变化
除配色外,还有两处深色模式专属行为:
- 导航栏首页封面模式:浅色模式下导航栏滚过首屏才变「亮」;深色模式因为首屏本身就是深色,逻辑以
.darkclass 优先 - 粒子特效画风切换:内容区浅色模式画飘落花瓣,深色模式画上升粒子 + 雾气 + 闪电;页脚粒子只在深色模式显示。见 粒子特效与动效
改造提示
- localStorage 键名
keqing-theme定义在ThemeContext.jsx,fork 后如需更换站点标识可一并修改(不修改也能正常运行) - 新增受主题控制的颜色:在
theme.config.js的colors.light和colors.dark中各添加一个同名字段(如bannerBg),保存后全站即可使用var(--banner-bg)引用,浅色 / 深色模式自动切换