配色方案

1280 字
6 分钟
配色方案

建议原则:

  1. 主题色只影响 5 类元素:主按钮、导航选中态、勾选框/开关、焦点环、当前 Tab 高亮
  2. 状态色(橙/红/绿)不随主题变,保持语义稳定
  3. 灰阶随主题做微调(暖主题用暖灰,冷主题用冷灰),这是”高级感”的关键
  4. 用 HSL/OKLCH 变量,方便同一套色自动生成 hover / soft 背景

二、配色方案(项目名 Emulsion = 胶片乳剂,用胶片命名很贴切)#

主题定位PrimaryHoverSoft 背景页面背景说明
银盐 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

styles/theme.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

tailwind.config.js
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

theme/accent.ts
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

theme/AccentProvider.tsx
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

config.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
}

如果你已有设置结构,直接加一个字段即可。


六、落地检查清单#

  1. 全局 grep 硬编码的 bg-black、bg-zinc-900、#18181b → 替换成 bg-primary
  2. 左侧导航选中态:bg-primary-soft text-primary-soft-fg,可加 border-l-2 border-primary
  3. 顶部 Tab(本地存储 / S3 …)选中态同上
  4. Checkbox / Switch / Radio 的 checked 色用 --primary
  5. 搜索框 focus 用 ring-primary/40
  6. 状态徽标(孤立/缺失/已关联)保持独立变量,不要挂到 accent 上
  7. 柯达主题下”孤立文件”橙色与主色接近,可把警告色稍微往红偏(--warning: 24 95% 45%)或保持不动,视觉上验证一下
  8. 深色模式:同样的 accent id 下另写一套 .dark[data-accent=...],把 --primary 提亮 10–15% 的 L 值即可复用

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

配色方案
https://shaio.top/posts/03mogallery/desktop/260905配色方案/
作者
沙海
发布于
2026-09-05
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
沙海
Hello, I'm Shai.
公告
欢迎来到我的博客!这是一则示例公告。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
84
分类
15
标签
48
总字数
67,035
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
GitHub Actions
博客版本
Firefly v6.12.2
文章许可
CC BY-NC-SA 4.0

文章目录