一次以减法为主的博客改造:时间线、去装饰与中文排版
这一轮改造的主线是减法。做完之后统计了一下:新增 4 个组件和 2 条分页路由,删除 16 个源码文件、整个 docs/ 目录和 6 项功能。页面上留下来的东西更少,但每一样都有明确的存在理由。
下面按主题记录,重点是每个决定背后的依据,而不是改了哪几行。
一、三个列表页统一为时间线
改造前,三个列表页各说各话:
- 首页:文章卡片和短文块混排,标题在左、日期在右
- 文章列表:按年份分组的紧凑单行,日期是
07-07 - 短文列表:左边框 + 右侧日期
同一个站点里三套视觉语言,从首页点进文章列表,眼睛要重新适应一次。
现在统一成一条竖线加圆点的时间线:文章是实心点,短文是空心点,日期一律 2026-07-07 18:33:32 周二,左对齐。首页因为混排,圆点后面额外带一个「文章 / 短文」标签;另外两个页面整页同类,不需要标签。
为了保证三处渲染完全一致,抽了四个组件:
| 组件 | 职责 |
|---|---|
Timeline.astro | 时间线容器,左边框即竖线 |
TimelineItem.astro | 单条:圆点 + 时间 + 可选类型标签,正文走 slot |
PostTimelineItem.astro | 文章条目,首页和文章列表共用 |
TimelineStats.astro | 页尾统计 |
圆点和竖线的对齐是这里唯一有技术含量的地方。圆点绝对定位,左移量等于容器内边距 + 边框宽度的一半 + 圆点半径,也就是 start-[calc(-1.5rem-5px)]。这个值和容器的 ps-6 是配套的,改一个必须改另一个,所以在两个组件里都写了注释说明这层耦合。
二、文章和短文都加了分页
两个列表页原来都是一次性输出全部内容。现在改成 Astro 的 [...page] 分页路由,URL 保持不变:第一页仍是 /posts 和 /notes,之后是 /posts/2、/notes/2。
分页大小拆成了两套配置,因为短文比文章短得多,密度不该一样:
posts: { perPage: 4, perIndex: 4 },
notes: { perPage: 10, perIndex: 4 },
需要注意的是 /posts/[...page] 和已有的文章详情路由 /posts/[...slug] 在同一层。构建时验证过:两者各自生成自己的路径集合,不冲突,也没有警告。
页尾统计的位置是特意选的。原来每个年份分组上方有一个「2026 · 4 篇」的标题,从首页点「全部文章」进来,第一眼是个大号年份,节奏被打断。现在年份分组整个去掉——条目本身已经带完整年份,再来个标题是重复信息——统计挪到列表末尾,也就是分页所在的位置,显示为「共 4 篇 · 2026 4 篇」。统计的是全站总数,不是当前页。
三、删掉的六项功能
| 功能 | 删除理由 |
|---|---|
| 标签系统 | 4 篇文章 6 个标签,其中「折腾」覆盖 100%(零区分度),css 和 font 各只有 1 篇(死胡同)。个人博客不是知识库 |
| 返回按钮 | 浏览器返回能恢复列表滚动位置,它只能跳到列表顶部,更差 |
| 回到顶部 | 同上,功能与浏览器/手势重复 |
| 阅读进度条 | 长文里持续存在的视觉噪音 |
| 编辑页面链接 | 个人博客没有协作者,这个入口面向的是不存在的用户 |
| 上一篇 / 下一篇 | 时间上相邻的两篇文章通常没有内容关联 |
删除时的连带清理比功能本身多。以标签为例,除了两个路由页和 Tag.astro,还牵出:Breadcrumb.astro(只有标签页在用,成了死代码)、getUniqueTags.ts、slugify.ts 里的 slugifyAll、i18n 的四条文案、文章 schema 的 tags 字段。返回按钮牵出的更远——Main.astro 的 data-backUrl、首页的 data-home-path、搜索页记录 backUrl 的三处代码。
顺带发现两个组件在之前的改动中已经没人引用:Card.astro(首页改时间线、标签页删除后失去全部调用方)和几个只服务于已删功能的图标。
页面上的装饰线也一并去掉了:页头下方、页尾上方、文末分隔线、列表页统计上方。去掉线之后页尾需要补偿,做法不是把线加回来,而是降级 + 拉开留白——页脚整体改成 text-muted-foreground text-sm,上方留白从 24px 提到 48px。用层级替代分隔线,这是去线设计能成立的前提。
四、目录改成横线式
桌面端的文章目录原来是一个展开的标题列表,长期占着右侧一块。现在默认只显示长短横线:h2 是 16px 的线,h3 是 8px。
- 读到哪一节,哪条线点亮(沿用原有的
IntersectionObserver) - 鼠标移上去才展开标题,容器是
w-fit,收起时只有横线那么宽,不会大片区域误触 - 一个图钉按钮可以把展开状态固定住,存在
localStorage里
横线长短不同会让标题起始位置参差,所以给横线套了一层固定宽度的容器,长短只体现在线本身,标题一律从同一个位置开始。
移动端保持原来的内联折叠目录——横线式目录需要正文两侧的留白,窄屏没有。
五、配色:从冷白蓝到暖纸墨绿
先测了原配色的对比度,发现两个实际缺陷:
- 深色模式的边框是橙褐色
#ab4b08。这在页头页尾还只是两条线时无所谓,但时间线的竖线用的正是这个变量——深色下一条棕橙色的线贯穿全页,和橙色圆点同色系,圆点的标记作用被抵消了。 - 深色模式下强调色上的白字只有 2.86:1,不满足 AA。它用在文本选中的样式上,选中时几乎看不清。
修完这两个之后,重新考虑了整套色板。原来的浅色背景是 #fdfdfd,亮度 98.2%,接近纯白。这对中文衬线是最不友好的组合:宋体系横画极细,在高亮度纯白背景上细笔画会产生光晕,长文读十分钟就累。
新色板:
| 变量 | 浅色 | 深色 |
|---|---|---|
--background | #faf8f4 暖纸 | #1f1e1c 暖黑 |
--foreground | #2c2a26 | #e8e4dc |
--accent | #2f6b5f 墨绿 | #7fbfae |
--muted-foreground | #5f5a52 | #a9a49a |
--border | #dbd3c6 | #423d35 |
对比度:正文 13.50 / 13.14,强调色 5.84 / 7.90,次要文字 6.45 / 6.71。全部远超 AA 4.5:1。改造前浅色的次要文字只有 4.75,卡在及格线上,而它承担着日期、页脚、统计等全部次要信息,且都是小字。
代码块的深色主题也跟着从 night-owl 换成了 min-dark。前者是深蓝底 #011627,配暖黑页面会是一块蓝色孤岛;后者底色 #1f1f1f,和页面几乎同级,且与已在使用的 min-light 是同一套设计。
强调色的用量比色相更重要。 墨绿定下来之后发现整页还是偏彩,原因是 accent 同时充当文章标题色、列表符号色、引用条颜色——标题是页面上字号最大、字重最重的元素,把它染成强调色,强调色就不再是强调色而是主色。现在标题改回正文色、悬停才变绿,列表符号降为弱灰。墨绿只剩下时间线圆点、目录高亮、导航当前项和交互反馈。
六、中文排版
从构建产物的 CSS 里读到三个硬数据,都不符合中文长文阅读:
.app-prose没有设置line-height,正文继承的是 Tailwind preflight 的 1.5- 段落间距
0.8em= 12.8px,不到半行 - 正文 16px,容器 768px,每行约 48 个汉字
对应的修改:
- 行高 1.5 → 1.8。汉字是全角、笔画密,行距不够时上下行会互相干扰。中文正文的通行区间是 1.7–2.0。
- 段距 0.8em → 1.4em。原来段落之间几乎粘连,只能靠语义断句。
- 字号 16px → 17px / 18px(
sm断点)。中文在同 px 下比西文视觉更小,因为西文有大量空白字腔,汉字是密排方块。这同时解决了行长问题:18px 时每行约 43 字,落回中文舒适区(30–45 字)。
还修了三处从模板继承来的西文假设:
blockquote的斜体。中文没有真正的意大利体,浏览器只能做合成倾斜,把字形整体切变,笔画粗细和字面结构都会失真。同样的问题之前还出现在h3上。- 行内代码的上下内边距。原来是
p-1,四周都有 4px,一段话里出现几个行内代码,行距就会参差。改成只留左右内边距,并加了0.15em的外边距,中英混排时不至于贴着汉字。 - 表格字号。
prose默认压到0.875em,中文在表格里本来就挤。
最后理了一遍字号阶梯。提高正文字号有个副作用:h2 用的是 em 相对单位,跟着从 24px 涨到 27px,而 h1 是固定的 30px——两者只差 3px,章节标题几乎和文章标题一样大,层级塌了。重新排成 ~1.2 倍的比例:
| 层级 | 字号 |
|---|---|
| 文章标题 h1 | 30px |
| 正文 h2 | 24.3px |
| 正文 h3 | 20.7px |
| 正文 h4 / 正文 | 18px |
| 日期、页脚 | 14px |
阅读态的字号收归到 .app-prose 一处定义。这个类正好只用在四个需要逐字阅读的地方:文章正文、关于页、首页和短文页的短文正文。定在这里,四处一次同步,新增页面挂上就自动一致。
一点体会
这一轮里,改动最大的几个决定都不是「加个什么功能」,而是「这个东西为什么还在」。标签、返回按钮、回到顶部、进度条——它们都是模板自带的,看起来都很合理,但放到「4 篇文章的个人博客」这个具体语境里,没有一个站得住。
另一个反复出现的模式是:问题往往不在被抱怨的那个属性上。觉得橙色太重,其实是强调色面积太大;觉得文章标题比站名大不协调,其实是 h1 和 h2 只差 3px;觉得页尾少了线不踏实,其实是页尾文字没有降级。换颜色、改字号、加回横线都是治标。