配色方案
1280 字
6 分钟
配色方案
建议原则:
- 主题色只影响 5 类元素:主按钮、导航选中态、勾选框/开关、焦点环、当前 Tab 高亮
- 状态色(橙/红/绿)不随主题变,保持语义稳定
- 灰阶随主题做微调(暖主题用暖灰,冷主题用冷灰),这是”高级感”的关键
- 用 HSL/OKLCH 变量,方便同一套色自动生成 hover / soft 背景
二、配色方案(项目名 Emulsion = 胶片乳剂,用胶片命名很贴切)
| 主题 | 定位 | Primary | Hover | Soft 背景 | 页面背景 | 说明 |
|---|---|---|---|---|---|---|
| 银盐 Silver(默认) | 当前中性风格 | #18181b | #27272a | #f4f4f5 | #fafafa | 保留现状 |
| 柯达 Kodak | 暖金黄 | #c9860a | #a86e05 | #fdf5e3 | #fcfaf6 | 摄影感最强,与橙色状态相近,注意区分 |
| 富士 Fuji | 深翠绿 | #0f7a5c | #0b5f48 | #e5f4ee | #f8fbf9 | 清爽、护眼、专业 |
| 爱克发 Agfa | 砖红 | #c2410c | #9a3412 | #fdece4 | #fcf9f7 | 复古、有冲击力 |
| 依尔福 Ilford | 石板蓝灰 | #3b5b8a | #2e4a72 | #e9eef6 | #f8f9fb | 黑白胶片品牌,沉稳工具感 |
| 宝丽来 Polaroid | 靛紫 | #5b5bd6 | #4747b8 | #ecebfb | #f9f9fc | 现代、年轻,偏 SaaS |
| 樱花 Sakura(可选) | 玫粉 | #c2497a | #9d3762 | #fbe9f0 | #fcf9fa | 柔和,给女性向用户 |
每个主题内附带 对比度检查:以上 Primary 在白底上的对比度均 ≥ 4.5:1(柯达金稍弱,白字建议用 #1c1500 深字或加深到 #b0740a)。
选中态处理建议(左侧导航”存储整理”):
- 背景用
primary-soft,文字/图标用primary,左侧可加 2px 的primary竖线,比现在纯灰更有辨识度。
三、Token 设计
CSS
:root,[data-accent="silver"] { --bg: 0 0% 98%; --card: 0 0% 100%; --fg: 240 10% 4%; --muted: 240 5% 96%; --muted-fg: 240 4% 46%; --border: 240 6% 90%;
--primary: 240 6% 10%; --primary-hover: 240 5% 15%; --primary-fg: 0 0% 98%; --primary-soft: 240 5% 96%; /* 选中态背景 */ --primary-soft-fg: 240 6% 10%; --ring: 240 6% 10%;
/* 语义色:不随主题变 */ --success: 142 71% 35%; --warning: 32 95% 44%; --danger: 0 72% 51%; --info: 217 91% 60%;}
[data-accent="kodak"] { --bg: 40 40% 98%; --border: 40 20% 89%; --muted: 40 30% 95%; --muted-fg: 40 8% 45%; --primary: 39 90% 41%; --primary-hover: 39 94% 34%; --primary-fg: 40 60% 6%; --primary-soft: 40 87% 94%; --primary-soft-fg: 39 94% 30%; --ring: 39 90% 41%;}
[data-accent="fuji"] { --bg: 150 30% 98%; --border: 150 12% 89%; --muted: 150 20% 95%; --muted-fg: 150 6% 44%; --primary: 162 78% 27%; --primary-hover: 162 80% 21%; --primary-fg: 0 0% 100%; --primary-soft: 156 40% 93%; --primary-soft-fg: 162 78% 22%; --ring: 162 78% 27%;}
[data-accent="agfa"] { --bg: 25 40% 98%; --border: 25 18% 89%; --muted: 25 30% 95%; --muted-fg: 25 8% 45%; --primary: 17 88% 40%; --primary-hover: 17 88% 32%; --primary-fg: 0 0% 100%; --primary-soft: 20 86% 94%; --primary-soft-fg: 17 88% 32%; --ring: 17 88% 40%;}
[data-accent="ilford"] { --bg: 220 25% 98%; --border: 220 14% 89%; --muted: 220 20% 95%; --muted-fg: 220 8% 45%; --primary: 216 40% 39%; --primary-hover: 216 43% 31%; --primary-fg: 0 0% 100%; --primary-soft: 216 42% 94%; --primary-soft-fg: 216 43% 31%; --ring: 216 40% 39%;}
[data-accent="polaroid"] { --bg: 240 25% 98%; --border: 240 14% 90%; --muted: 240 20% 95%; --muted-fg: 240 6% 46%; --primary: 240 60% 60%; --primary-hover: 240 45% 50%; --primary-fg: 0 0% 100%; --primary-soft: 243 67% 95%; --primary-soft-fg: 240 45% 45%; --ring: 240 60% 60%;}如果用 Tailwind(看风格大概率是 shadcn/ui):
JavaScript
colors: { background: 'hsl(var(--bg))', border: 'hsl(var(--border))', primary: { DEFAULT: 'hsl(var(--primary))', hover: 'hsl(var(--primary-hover))', foreground: 'hsl(var(--primary-fg))', soft: 'hsl(var(--primary-soft))', 'soft-foreground': 'hsl(var(--primary-soft-fg))', }, // ...}这样现有 bg-primary text-primary-foreground 的组件一行不改就能换色。
四、React 侧实现
React
export const ACCENTS = [ { id: 'silver', name: '银盐', color: '#18181b' }, { id: 'kodak', name: '柯达', color: '#c9860a' }, { id: 'fuji', name: '富士', color: '#0f7a5c' }, { id: 'agfa', name: '爱克发', color: '#c2410c' }, { id: 'ilford', name: '依尔福', color: '#3b5b8a' }, { id: 'polaroid', name: '宝丽来', color: '#5b5bd6' },] as const;export type AccentId = typeof ACCENTS[number]['id'];React
import { createContext, useContext, useEffect, useState } from 'react';import { GetAccent, SetAccent } from '../../wailsjs/go/main/App';import { WindowSetBackgroundColour } from '../../wailsjs/runtime';import { ACCENTS, AccentId } from './accent';
const Ctx = createContext<{ accent: AccentId; setAccent: (a: AccentId) => void }>(null!);
export function AccentProvider({ children }: { children: React.ReactNode }) { const [accent, setAccentState] = useState<AccentId>( () => (localStorage.getItem('accent') as AccentId) || 'silver' // 先用缓存避免闪烁 );
useEffect(() => { GetAccent().then(a => a && setAccentState(a as AccentId)); }, []);
useEffect(() => { document.documentElement.dataset.accent = accent; localStorage.setItem('accent', accent); // 同步窗口底色,避免 resize 时露白/露黑 const bg = getComputedStyle(document.documentElement).getPropertyValue('--bg'); // 可选:把 hsl 转 rgb 后传给 WindowSetBackgroundColour(r,g,b,255) }, [accent]);
const setAccent = (a: AccentId) => { setAccentState(a); SetAccent(a); }; return <Ctx.Provider value={{ accent, setAccent }}>{children}</Ctx.Provider>;}export const useAccent = () => useContext(Ctx);避免首屏闪烁:在 index.html 的 <head> 里加一段内联脚本:
HTML
<script> document.documentElement.dataset.accent = localStorage.getItem('accent') || 'silver';</script>选择器 UI(放在左下角”浅色”下拉旁,或设置页):
React
export function AccentPicker() { const { accent, setAccent } = useAccent(); return ( <div className="flex gap-2"> {ACCENTS.map(a => ( <button key={a.id} title={a.name} onClick={() => setAccent(a.id)} className={cn('h-6 w-6 rounded-full border-2 transition', accent === a.id ? 'border-foreground scale-110' : 'border-transparent')} style={{ background: a.color }} /> ))} </div> );}五、Go 侧持久化
Go
type Settings struct { Theme string `json:"theme"` // light / dark / system Accent string `json:"accent"` // silver / kodak / ... Lang string `json:"lang"`}
func (a *App) GetAccent() string { return a.settings.Accent }
func (a *App) SetAccent(id string) error { allowed := map[string]bool{"silver": true, "kodak": true, "fuji": true, "agfa": true, "ilford": true, "polaroid": true} if !allowed[id] { return fmt.Errorf("invalid accent: %s", id) } a.settings.Accent = id return a.saveSettings() // 写入 os.UserConfigDir()/emulsion/settings.json}如果你已有设置结构,直接加一个字段即可。
六、落地检查清单
- 全局 grep 硬编码的
bg-black、bg-zinc-900、#18181b→ 替换成bg-primary - 左侧导航选中态:
bg-primary-soft text-primary-soft-fg,可加border-l-2 border-primary - 顶部 Tab(本地存储 / S3 …)选中态同上
- Checkbox / Switch / Radio 的 checked 色用
--primary - 搜索框 focus 用
ring-primary/40 - 状态徽标(孤立/缺失/已关联)保持独立变量,不要挂到 accent 上
- 柯达主题下”孤立文件”橙色与主色接近,可把警告色稍微往红偏(
--warning: 24 95% 45%)或保持不动,视觉上验证一下 - 深色模式:同样的 accent id 下另写一套
.dark[data-accent=...],把--primary提亮 10–15% 的 L 值即可复用
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章 智能推荐
1
本地资源库视频播放
MO Gallery 本地资源库视频播放
2
Desktop上传链路优化
MO Gallery Desktop上传链路优化
3
首页UI优化
MO Gallery 首页UI优化
4
插件功能
MO Gallery 插件功能
5
色卡分析算法优化
MO Gallery 色卡分析算法优化
随机文章 随机推荐