Texto 主题开发指南
主题文件结构
一个 Texto 主题是一个 CSS 文件,包含三个块:
/* 浅色模式:所有变量的浅色值 */
:root {
--background: ...;
--foreground: ...;
/* ... 全部 33 个变量 + 可选的 --warning */
}
/* 深色模式:所有变量的深色值 */
.dark {
--background: ...;
--foreground: ...;
/* ... 全部 33 个变量 + 可选的 --warning */
}
/* 编辑器内容区域:代码/高亮/选中样式 */
#writer {
--highlight-color: ...;
--code-editor-theme-light: ...;
/* ... 编辑器专用变量 + 自定义内容样式 */
}
变量清单
一、核心颜色变量
共 33 个变量:32 个标准颜色变量 + --color-scheme。以下表格中还包含一个推荐定义的 --warning。按分组列出。
Surface —— 主表面
| 变量 | 作用 | 视觉说明 |
|---|---|---|
--background |
整个应用最底层的背景色 | 类似纸张的底色 |
--foreground |
在背景上的默认文本色 | 正文、标题、标签的颜色 |
--card |
卡片组件的背景色 | 比背景略不同的面板底色 |
--card-foreground |
在卡片上的文本色 | 卡片中的文字颜色 |
--popover |
弹出层、菜单、提示框的背景色 | 浮动层的底色 |
--popover-foreground |
在弹出层上的文本色 | 菜单项、提示文字的颜色 |
Accents —— 强调色
| 变量 | 作用 | 视觉说明 |
|---|---|---|
--primary |
主色调,用于选中、焦点、交互态 | 最突出的强调色 |
--primary-foreground |
在主色调背景上的文本色 | 主色调按钮上的文字 |
--secondary |
次要表面色 | 比主背景稍有不同的面板色 |
--secondary-foreground |
在次要表面上的文本色 | 次要面板的文字 |
--accent |
高亮/强调色,用于悬停、选中样式 | 鼠标悬停、选中项的背景 |
--accent-foreground |
在高亮背景上的文本色 | 选中项的文字颜色 |
--breathe-color |
呼吸动画色 | 文件修改指示点的脉冲动画颜色 |
Feedback —— 反馈色
| 变量 | 作用 | 视觉说明 |
|---|---|---|
--destructive |
危险/错误/删除操作的颜色 | 红色系,用于错误提示、删除按钮 |
--warning |
警告状态的颜色(可选,推荐定义) | 橙色/黄色系,用于冲突、警告提示 |
--muted |
弱化背景色 | 比背景略深/浅,用于次要区域 |
--muted-foreground |
弱化文本色 | 用于描述、提示、占位、次要文字 |
Boundaries —— 边界色
| 变量 | 作用 | 视觉说明 |
|---|---|---|
--border |
所有边框的默认颜色 | 面板边框、分割线、卡片描边 |
--input |
输入框的边框颜色 | 文本框、下拉框的边框 |
--ring |
焦点环的颜色 | 点击输入框或按钮时的外发光 |
Charts —— 图表色
| 变量 | 作用 |
|---|---|
--chart-1 |
图表配色 1 |
--chart-2 |
图表配色 2(同时用于标题栏"已保存"状态色) |
--chart-3 |
图表配色 3 |
--chart-4 |
图表配色 4 |
--chart-5 |
图表配色 5 |
Sidebar —— 侧边栏色
侧边栏有自己独立的一套颜色,通常比主色调稍暗(浅色模式)或稍亮(深色模式)。
| 变量 | 作用 | 视觉说明 |
|---|---|---|
--sidebar |
侧边栏背景色 | 文件树区域的底色 |
--sidebar-foreground |
侧边栏文本色 | 文件名、目录名的颜色 |
--sidebar-primary |
侧边栏主色调 | 侧边栏中的强调色 |
--sidebar-primary-foreground |
侧边栏主色调上的文本色 | — |
--sidebar-accent |
侧边栏选中/悬停背景色 | 选中的文件、悬停项的背景 |
--sidebar-accent-foreground |
侧边栏选中项文本色 | 选中文件的文字颜色 |
--sidebar-border |
侧边栏边框颜色 | 侧边栏与应用主体的分隔线 |
--sidebar-ring |
侧边栏焦点环颜色 | 侧边栏中元素聚焦时的外发光 |
特殊变量
| 变量 | 作用 | 取值 |
|---|---|---|
--color-scheme |
浏览器原生 UI 的配色方案 | light 或 dark(字符串,不是颜色值) |
控制滚动条、表单控件等系统原生元素的样式。
二、编辑器内容区域的变量(在 #writer {} 中定义)
| 变量 | 作用 |
|---|---|
--highlight-color |
文本高亮标记(<mark>)的背景色 |
--default-selection |
编辑区中选中文本的背景色(可选,不定义则使用浏览器默认选中色) |
--code-editor-theme-light |
浅色模式代码块的语法高亮主题名 |
--code-editor-theme-dark |
深色模式代码块的语法高亮主题名 |
--source-code-theme-light |
浅色模式源代码编辑器的语法高亮主题名 |
--source-code-theme-dark |
深色模式源代码编辑器的语法高亮主题名 |
--code-editor-theme-* 和 --source-code-theme-* 的可用值(语法高亮主题名称):
oneDark materialDark githubDark githubLight
dracula atomone vscodeDark xcodeDark
xcodeLight eclipse sublime basicLight
tokyoNightDay bbedit solarizedLight
三、编辑器内容样式(在 #writer {} 中定义)
以下选择器可用于自定义编辑器内容区域的样式:
#writer h1 /* 一级标题 */
#writer h2 /* 二级标题 */
#writer h3 /* 三级标题 */
#writer h4 /* 四级标题 */
#writer h5 /* 五级标题 */
#writer h6 /* 六级标题 */
#writer p /* 段落 */
#writer a /* 链接 */
#writer code /* 行内代码 */
#writer pre /* 代码块 */
#writer pre code /* 代码块内的代码(清除行内代码样式) */
#writer blockquote /* 引用块 */
#writer ul /* 无序列表 */
#writer ol /* 有序列表 */
#writer li /* 列表项 */
#writer ul li::marker /* 无序列表标记点颜色 */
#writer ol li::marker /* 有序列表编号颜色 */
#writer hr /* 分割线 */
#writer table th /* 表格表头 */
#writer table td /* 表格单元格 */
#writer mark /* 高亮标记 */
#writer ::selection /* 文本选中样式 */
颜色格式
主题 CSS 文件中可以使用 hex、hsl、oklch 任意格式:
--primary: #3b82f6;
--primary: hsl(217, 91%, 60%);
--primary: oklch(0.546 0.245 262.881);
但视觉主题编辑器只完整支持 oklch 格式。 使用 hex 或 hsl 的值虽然能在 CSS 中正常生效,但在编辑器的分组面板中不会被显示,且通过取色器编辑后会自动转为 oklch 格式。
推荐直接使用 OKLCH。它更接近人眼感知,色相一致性好,支持 color-mix() 函数。
推荐工具:OKLCH Converter
颜色设计原则
每对 background/foreground 变量要保证可读性:
--background / --foreground 主表面
--card / --card-foreground 卡片表面
--popover / --popover-foreground 弹出层
--primary / --primary-foreground 主强调色
--secondary / --secondary-foreground 次要色
--muted / --muted-foreground 弱化色
--accent / --accent-foreground 交互高亮色
--sidebar / --sidebar-foreground 侧边栏
典型关系参考:
--foreground在--background上高对比度(如 #111 在 #fff 上)--muted-foreground比--foreground更淡(如 #666 在 #fff 上)--muted略深于--background(如 #f5f5f5 在 #fff 上)--border比背景深 10-15%--primary是应用中最醒目的颜色--sidebar系列通常与主色系略有区别
高亮颜色(mark 标签)
--highlight-color 在主题中定义一个默认值,但用户可以在设置中切换六种预设颜色。预设值分别是:
黄色 oklch(0.9 0.15 85 / 0.35)
绿色 oklch(0.9 0.15 140 / 0.35)
蓝色 oklch(0.85 0.1 250 / 0.35)
粉色 oklch(0.9 0.1 350 / 0.35)
橙色 oklch(0.9 0.15 60 / 0.35)
紫色 oklch(0.85 0.12 300 / 0.35)
主题中定义的 --highlight-color 只在用户未主动切换时生效。
自定义主题变量
可以定义主题独有的 CSS 变量来组织颜色:
:root {
--mytheme-code-bg: color-mix(in oklch, var(--primary) 10%, var(--background));
--mytheme-link-color: var(--primary);
--mytheme-blockquote-bg: var(--muted);
}
.dark {
--mytheme-code-bg: color-mix(in oklch, var(--primary) 15%, var(--background));
}
#writer code {
background: var(--mytheme-code-bg);
}
#writer a {
color: var(--mytheme-link-color);
}
安全限制
导入主题时以下内容会被拒绝:
| 内容 | 原因 |
|---|---|
url(http 或 url(https |
禁止引用外部资源 |
@import |
禁止加载外部样式 |
@font-face |
字体通过应用设置管理 |
配色思路建议
- 从
--background和--foreground开始,确定底色和文字色 - 确定
--primary和--muted,这是使用最广的两个变量 - 用
--muted-foreground设置次要文字,让界面有层次 - 确定
--border,比背景深 10-15% 即可 - 侧边栏独立配色,通常比主区略深形成视觉区分
- 最后调
--chart-1到--chart-5,确保五色可区分 - 深色模式:深色不是浅色的反色。色相要偏移(通常偏蓝),饱和度降低,对比度保持
完整主题模板
/**
* 主题名称
* 简短描述
*/
/* ==================== 浅色模式 ==================== */
:root {
/* ---- Surface ---- */
--background: oklch(1 0 0);
--foreground: oklch(0.25 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.25 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.25 0 0);
/* ---- Accents ---- */
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--breathe-color: oklch(0.646 0.222 41.116);
/* ---- Feedback ---- */
--destructive: oklch(0.577 0.245 27.325);
--warning: oklch(0.621 0.178 26.1);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
/* ---- Boundaries ---- */
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
/* ---- Charts ---- */
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
/* ---- Sidebar ---- */
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.25 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.9 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
/* ---- Special ---- */
--color-scheme: light;
}
/* ==================== 深色模式 ==================== */
.dark {
--background: oklch(0.176 0.014 258.4);
--foreground: oklch(0.943 0.011 243.7);
--card: oklch(0.22 0.016 256.8);
--card-foreground: oklch(0.943 0.011 243.7);
--popover: oklch(0.22 0.016 256.8);
--popover-foreground: oklch(0.943 0.011 243.7);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.176 0.014 258.4);
--secondary: oklch(0.267 0.015 256.8);
--secondary-foreground: oklch(0.943 0.011 243.7);
--accent: oklch(0.267 0.015 256.8);
--accent-foreground: oklch(0.943 0.011 243.7);
--breathe-color: oklch(0.715 0.152 253.3);
--destructive: oklch(0.586 0.201 26.8);
--warning: oklch(0.668 0.164 24.7);
--muted: oklch(0.267 0.015 256.8);
--muted-foreground: oklch(0.662 0.018 250.9);
--border: oklch(0.33 0.015 252.3);
--input: oklch(0.5 0.015 256.8);
--ring: oklch(0.715 0.152 253.3);
--chart-1: oklch(0.715 0.152 253.3);
--chart-2: oklch(0.695 0.181 145.6);
--chart-3: oklch(0.72 0.14 79.9);
--chart-4: oklch(0.73 0.15 34.1);
--chart-5: oklch(0.732 0.167 301.7);
--sidebar: oklch(0.22 0.016 256.8);
--sidebar-foreground: oklch(0.943 0.011 243.7);
--sidebar-primary: oklch(0.715 0.152 253.3);
--sidebar-primary-foreground: oklch(0.943 0.011 243.7);
--sidebar-accent: oklch(0.32 0.015 256.8);
--sidebar-accent-foreground: oklch(0.943 0.011 243.7);
--sidebar-border: oklch(0.33 0.015 252.3);
--sidebar-ring: oklch(0.715 0.152 253.3);
--color-scheme: dark;
}
/* ==================== 编辑器内容区域 ==================== */
#writer {
--highlight-color: oklch(0.9 0.15 85 / 0.35);
--default-selection: oklch(0.6 0.25 255 / 0.3);
--code-editor-theme-light: githubLight;
--code-editor-theme-dark: githubDark;
--source-code-theme-light: githubLight;
--source-code-theme-dark: githubDark;
}
#writer ::selection {
background: var(--default-selection);
}
/* ---- 自定义内容样式 ---- */
#writer h1 {
position: relative;
padding-bottom: 0.5em;
border-bottom: 1px solid var(--border);
}
#writer a {
color: var(--primary);
text-decoration: none;
border-bottom: 1px solid color-mix(in oklch, var(--primary) 25%, transparent);
}
#writer code {
padding: 0.2em 0.4em;
background: color-mix(in oklch, var(--foreground) 6%, transparent);
border-radius: 4px;
font-size: 0.85em;
}
#writer blockquote {
border-left: 4px solid var(--border);
padding: 0 1em;
color: var(--muted-foreground);
}
#writer hr {
height: 1px;
background: var(--border);
border: 0;
}
#writer table th {
background: var(--muted);
font-weight: 600;
}
#writer mark {
background: var(--highlight-color);
color: inherit;
}
#writer ul li::marker {
color: var(--primary);
}
#writer ol li::marker {
color: var(--primary);
font-weight: 500;
}
调试方式
- 在主题编辑器中选择"源代码"模式,直接编辑主题 CSS
- 保存后效果即时生效
- 应用内置了三个主题(默认为黑白灰、樱染为粉红调、惊蛰为绿色调),可作为配色参考
导出与分享
在主题编辑器中选中主题,点击"导出",保存为 .css 文件分享给他人。对方通过"导入"功能使用。