跳转到内容
陆上江南

一次以减法为主的博客改造:时间线、去装饰与中文排版AI

这一轮改造的主线是减法。做完之后统计了一下:新增 4 个组件和 2 条分页路由,删除 16 个源码文件、整个 docs/ 目录和 6 项功能。页面上留下来的东西更少,但每一样都有明确的存在理由。

下面按主题记录,重点是每个决定背后的依据,而不是改了哪几行。

一、三个列表页统一为时间线

改造前,三个列表页各说各话:

同一个站点里三套视觉语言,从首页点进文章列表,眼睛要重新适应一次。

现在统一成一条竖线加圆点的时间线:文章是实心点,短文是空心点,日期一律 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%(零区分度),cssfont 各只有 1 篇(死胡同)。个人博客不是知识库
返回按钮 浏览器返回能恢复列表滚动位置,它只能跳到列表顶部,更差
回到顶部 同上,功能与浏览器/手势重复
阅读进度条 长文里持续存在的视觉噪音
编辑页面链接 个人博客没有协作者,这个入口面向的是不存在的用户
上一篇 / 下一篇 时间上相邻的两篇文章通常没有内容关联

删除时的连带清理比功能本身多。以标签为例,除了两个路由页和 Tag.astro,还牵出:Breadcrumb.astro(只有标签页在用,成了死代码)、getUniqueTags.tsslugify.ts 里的 slugifyAll、i18n 的四条文案、文章 schema 的 tags 字段。返回按钮牵出的更远——Main.astrodata-backUrl、首页的 data-home-path、搜索页记录 backUrl 的三处代码。

顺带发现两个组件在之前的改动中已经没人引用:Card.astro(首页改时间线、标签页删除后失去全部调用方)和几个只服务于已删功能的图标。

页面上的装饰线也一并去掉了:页头下方、页尾上方、文末分隔线、列表页统计上方。去掉线之后页尾需要补偿,做法不是把线加回来,而是降级 + 拉开留白——页脚整体改成 text-muted-foreground text-sm,上方留白从 24px 提到 48px。用层级替代分隔线,这是去线设计能成立的前提。

四、目录改成横线式

桌面端的文章目录原来是一个展开的标题列表,长期占着右侧一块。现在默认只显示长短横线:h2 是 16px 的线,h3 是 8px。

横线长短不同会让标题起始位置参差,所以给横线套了一层固定宽度的容器,长短只体现在线本身,标题一律从同一个位置开始。

移动端保持原来的内联折叠目录——横线式目录需要正文两侧的留白,窄屏没有。

五、配色:从冷白蓝到暖纸墨绿

先测了原配色的对比度,发现两个实际缺陷:

  1. 深色模式的边框是橙褐色 #ab4b08。这在页头页尾还只是两条线时无所谓,但时间线的竖线用的正是这个变量——深色下一条棕橙色的线贯穿全页,和橙色圆点同色系,圆点的标记作用被抵消了。
  2. 深色模式下强调色上的白字只有 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 里读到三个硬数据,都不符合中文长文阅读:

  1. .app-prose 没有设置 line-height,正文继承的是 Tailwind preflight 的 1.5
  2. 段落间距 0.8em = 12.8px,不到半行
  3. 正文 16px,容器 768px,每行约 48 个汉字

对应的修改:

还修了三处从模板继承来的西文假设:

最后理了一遍字号阶梯。提高正文字号有个副作用: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;觉得页尾少了线不踏实,其实是页尾文字没有降级。换颜色、改字号、加回横线都是治标。