主题定制与功能扩展
Quartz 的配色、字体、UI 组件和性能优化,全在这一篇。
配色方案
选择历程
浅色主题换了好几轮:默认 → Catppuccin Latte → Nord Light → Vitesse Light → Snazzy Light,最后才定下来。暗色主题一直用 One Dark,没换过。
配置方式
在 quartz.config.ts 的 theme.colors 中定义 9 个颜色变量:
theme: {
colors: {
lightMode: {
light: "#FFFBF0", // 背景色
lightgray: "#E8E4DA", // 边框/分割线
gray: "#B0AC9F", // 次要文字
darkgray: "#505050", // 正文
dark: "#2B2B2B", // 标题
secondary: "#4876D6", // 链接/强调色
tertiary: "#FF6363", // 悬停色
highlight: "rgba(72, 118, 214, 0.08)",
textHighlight: "#FFF3B0",
},
darkMode: {
// One Dark 配色 ...
},
},
},代码高亮主题
Plugin.SyntaxHighlighting({
theme: {
light: "one-light",
dark: "one-dark-pro",
},
})字体
使用 LXGW WenKai(霞鹜文楷)作为中文字体,通过 CDN 加载:
theme: {
fontOrigin: "custom",
cdnCaching: false,
typography: {
header: "LXGW WenKai",
body: "LXGW WenKai",
code: "JetBrains Mono",
},
},在 Head.tsx 中添加字体 CSS 链接,使用 media="print" onload="this.media='all'" 技巧实现非阻塞加载。
UI 功能定制
已实现的功能
| 功能 | 实现方式 | 文件 |
|---|---|---|
| Giscus 评论 | 内置支持,配置 repoId/categoryId | quartz.config.ts |
| 顶部导航栏 | 自定义 Navbar 组件 | 自定义组件 |
| Logo + 标题 | 修改 PageTitle.tsx 添加图片 | quartz/components/PageTitle.tsx |
| 个人标语 | 添加 Tagline 组件 | 自定义组件 |
| 时间线页面 | 自定义 TimelineContent + timelinePage emitter | quartz/components/pages/TimelineContent.tsx |
| Explorer 文件夹图标 | SVG 图标替换默认箭头 | quartz/components/Explorer.tsx |
| 返回顶部按钮 | 纯 CSS/JS 组件 | 自定义组件 |
| 图片懒加载 | rehype 插件添加 loading="lazy" | quartz/plugins/transformers/ofm.ts |
| Lightbox 图片放大 | 社区插件 Clickable Images Zoom | quartz/plugins/transformers/clickableImages.ts |
| 阅读模式 | Quartz 内置 ReaderMode 组件 | 布局配置 |
| 统一 Tab 标题 | 固定为站点名称 | quartz/components/Head.tsx |
布局配置
在 quartz.layout.ts 中配置三栏布局:
// 左侧:Logo、标语、Explorer、搜索
// 中间:面包屑 + 文章内容 + 评论
// 右侧:目录(TOC)、暗色模式、阅读模式性能优化
PageSpeed 优化项
基于 Google PageSpeed Insights 的多轮优化:
| 优化项 | 做法 | 效果 |
|---|---|---|
| 字体非阻塞加载 | media="print" → onload="this.media='all'" | 消除渲染阻塞 |
| KaTeX CSS 异步 | 从 <link> 改为 JS 动态插入 | 消除渲染阻塞 |
| 图片压缩 | 大图压缩到合理尺寸 | 减少加载体积 |
| GIF 缩小 | 缩小尺寸 | 减少体积 |
| Giscus 懒加载 | IntersectionObserver 滚动到可见才加载 | 减少首屏请求 |
| TOC 性能 | 缓存 DOM 查询结果 | 减少重排 |
| contentIndex 分片 | 拆分为 48KB 元数据 + 3.7MB 搜索索引(按需加载) | 首屏减少 3.7MB |
| CDN 字体回退 | jsdelivr → zzko → elemecdn 三级回退 | 防止 CDN 被墙 |
| CSS 变量提取 | 7 个常用值提取为变量 | 维护性提升 |
移动端适配
overflow-x: hidden仅限移动端(桌面会破坏position: sticky)- 移除双重 padding(
#quartz-body和.center都有 padding 导致偏移) - 触摸目标 44×44px 最小尺寸
- 响应式字体和间距
这是系列文章的第三篇:
