为什么我又把个人网站重做了一遍
上一版网站用了现成模板。它不难看,也能用,但每加一个页面,我都得先猜模板的类名是什么意思,再决定要不要覆盖。几个月后,样式文件里堆满了 !important,而我仍然说不清首页那三栏在手机上是怎样折行的。
这次重做,我给自己定了三个约束:
- 静态站点,不引入前端框架;
- 不加载第三方统计、字体或图标脚本;
- 任何一个页面,在 3 秒内能读清主要内容,键盘也能走完。
前两条是技术选择,第三条是验收标准。它们决定了后面的很多细节。
先定阅读路径,再画页面
上一版从“首页要放什么”开始,结果首页塞了自我介绍、最新文章、项目卡片、友链、订阅框和一张很大的头像。每个模块都有一点用,但没有一个能让人停下來。
这次先写了一个只有五行的草稿:
我是谁 → 我做过什么 → 我最近在想什么 → 怎么联系我。
对应的就是首页的顺序:一句主张、三个事实、项目、笔记、关于、联系。导航只保留这四件事,其他链接放进页脚。页面少了,反而更容易把每一屏做清楚。
主题不是换一套颜色
最容易做的事是改 --bs-primary,然后宣布“自定义主题完成”。真正麻烦的是那些模板没管的地方:标题的中英文混排、代码块的横向滚动、深色模式下的边框对比度、目录在窄屏上的位置。
我把样式分成两层:
- 变量层:颜色、字体、圆角、阴影、容器宽度,全部放在
tokens.css; - 规则层:导航、首页、内页、页脚各自一个文件,只使用变量,不写死颜色。
这样深色模式不需要复制一套规则。只要在根元素上切换 data-theme,再让 Quarto 自己的 quarto-dark 类跟上:
html[data-theme="dark"] {
--cz-bg: #14110e;
--cz-ink: #f4ead9;
--cz-accent: #e98a5c;
}颜色不是越多越好。浅色模式用暖纸色做底,正文是偏暖的墨色;强调色只留给链接、按钮和少量标记。深色模式不是简单反色,而是把纸换成深棕,把橙色提亮,避免纯黑背景上的细字发虚。
Quarto 帮了大忙,也有自己的脾气
Quarto 的网站项目很适合这种站点:Markdown 写内容,YAML 管导航,Bootstrap 处理栅格,发布到 GitHub Pages 只需要一个 action。但它不是“零配置”。
我踩到的第一个坑是缩进。首页最初用原始 HTML 写,<div class="cz-hero"> 内部的空行和四空格缩进被 Pandoc 当成了代码块,整段 HTML 原样显示在页面上。后来改成 fenced div:
::: {.cz-hero}
...
:::这里还有一条规则:::: 的上一行必须是空行,下一行也要空一行。否则 Pandoc 会把围栏当成普通段落的一部分。这不是 Quarto 的 bug,是 Pandoc 的 Markdown 解析规则;知道以后就不再浪费时间怀疑人生。
第二个坑是页面宽度。Quarto 的 page-layout: custom 不会自动把内容容器居中,默认贴着左侧。自定义页面需要自己处理:
#quarto-content.page-layout-custom {
margin-inline: auto;
}第三个坑是链接。Quarto 不会阻止你写一个不存在的 href,但构建时会给出警告。把警告当错误看,顺手就能发现导航里指向 .qmd 而不是渲染后路径的链接。
发布应该是一条命令
网站最终放在 GitHub Pages 上。构建和发布都在 GitHub Actions 里完成,本地只负责写和预览:
quarto preview
quarto render发布工作流做三件事:安装 Quarto、渲染站点、把 _site 推到 gh-pages。第一次发布后,还要去仓库的 Settings → Pages 把来源改成 gh-pages。用户站点默认会指向 main,这一步很容易漏,漏了就会看到 404。
最后留下的检查清单
- 每个页面都有独立的
title和description; - 导航链接在本地渲染后仍然有效;
- 深色模式不是反色,而是重新检查过对比度;
- 键盘可以到达所有交互元素,焦点环清晰可见;
- 关闭动画后,内容仍然完整;
- 发布后打开线上地址,而不是只看本地预览。
网站不是一次做完的。它现在仍然有一些我想改的地方,比如项目页的筛选、文章的上一篇/下一篇。但至少这次,我知道每一层为什么存在,也知道下一次该从哪里开始。
这篇之后:我把这套主题、检查清单和发布流程收进了 dsh-quarto-website 插件。如果你也想用 Quarto 做一个自己的站点,可以从那里开始,而不是从一堆互相覆盖的 CSS 开始。