这个博客的视觉设计

设计建站

博客刚刚完成了一次视觉升级:明暗双主题。如果你点一下导航栏右上角的月亮图标,整个站点会沉入一片暖黑——文字变浅、主色提亮、图片调暗,过渡柔和得像日落。

借着这次改版,把视觉设计背后的想法整理成这篇文章。和往常一样,这篇文章本身就是用这套设计渲染出来的:你读到的每一个效果,都是它自己的示范。

设计的起点:阅读优先

个人博客的视觉设计,要回答的第一个问题不是「好不好看」,而是**「读起来累不累」**。

读者来到这里,目的几乎只有一个:读完一篇文章。所以所有的设计决策都围绕一件事展开——让文字成为页面上唯一的焦点。这意味着:

  • 单栏居中布局,阅读区固定 720px——恰好是一行 30 到 40 个汉字的宽度,视线不必长途跋涉
  • 没有侧边栏,没有弹窗,没有阅读进度条,没有任何和正文争夺注意力的元素
  • 动效只有两处克制的淡入,0.4 秒内完成,看完就忘

「不做什么」比「做什么」更难。每一处留白,都是从「还能再加点什么」的诱惑里抢回来的。

留白是内容的一部分

这个站点的留白多得有些「奢侈」:标题上方两倍多的间距、正文 1.9 倍的行高、段落之间充分的呼吸。

但我越来越觉得,留白不是「没有东西的地方」,而是内容的一部分。就像书法里的飞白、音乐里的休止符——文字需要周围的空间,才能被好好地读。挤在一起的文字只能被「看」,被空间包围的文字才能被「读」。

字体:霞鹜文楷

全站正文字体是霞鹜文楷,一款开源中文字体。选它的理由写在第一篇文章里了:笔画温润,长时间阅读不累。

中文字体是个大工程——每个字都是一幅小画,一个完整字库动辄数万个字形。所以它通过 CDN 按需分片加载:页面用到的字才下载,用不到的不会占带宽。这次升级顺手加了 preconnect,让浏览器在渲染 HTML 的同时就与字体服务器提前建连,省掉一段等待。

字体是网站的「声音」。霞鹜文楷的声音,接近一个人用钢笔在纸上慢慢写字——不是印刷体的规整,而是带一点手写的温度。这和这个博客想做的事是匹配的。

配色:暖白与教育蓝

浅色主题的底色是 #FAFAF8——不是纯白,而是掺了一点暖意的白。纯白在屏幕上太锋利了,尤其在夜里;暖白像宣纸,柔一点,也旧一点。

主色是 #4A90D9,一种被我们内部叫做「教育蓝」的颜色。它只在极少数地方出现:链接、二级标题前那条四像素的竖线、引用块的左边框、选中文字的底色。点缀,而不是铺陈——主色用得越省,出现时越有力。

明暗双主题:一盏可以切换的灯

这次升级的主角。深色模式不是把浅色「反相」一下就完事——直接反色会得到一种冷冰冰的蓝黑,而且对比度往往过头,读起来更累。这里的深色主题是单独调过的一套:

令牌 浅色主题 深色主题
背景 #FAFAF8 暖白 #1B1B19 暖黑
正文 #2C2C2C #E8E6E1
主色 #4A90D9 教育蓝 #6FB0EE 提亮蓝
代码块 #FBFAF8 浅底细边 #171715 深底

两个原则:延续暖调——深色背景同样带一点暖,像熄灯后的书房而不是关机的屏幕;压低对比——正文用的是米白而非纯白,深底上的纯白太刺眼,米白才能久读。图片在深色下会自动调暗 10%,免得一张亮图在黑夜里突兀得像手电筒。

切换的机制值得多说两句。最朴素的难题是刷新闪白:深色用户刷新页面时,浏览器总要先渲染一瞬间的白色。解法是把一段十几行的初始化脚本放在所有样式之前——它先读你的记忆(localStorage),没有记忆就读系统偏好(prefers-color-scheme),然后在 <html> 上盖一个 data-theme 的章,样式才会开始绘制。等你看见页面时,主题早已就位。

所以整个行为是:第一次来,跟随你的系统;点了按钮,记住你的选择。不弹提示,不挡内容,一个图标完成所有事。

移动端与性能

视觉设计的最后一公里在手机上。表格会被自动包进横向滚动的容器,长链接会老实换行,按钮和链接的触控区域放大到手指舒适的大小。

而性能本身也是一种视觉设计——一个加载迟缓的页面,再好看也是模糊的。这个站点现在全部产物 77KB,没有任何框架,唯一的脚本只有两段共 1.5KB 的内联主题代码。它应该在任何设备上都是「唰」地一下就出现,像翻开一页纸。

最后

视觉设计做到最后,会发现它其实是在回答一个问题:你想让访客处于什么样的状态?

我的答案是:安静。像一间光线刚好的书房——白天是暖白的纸页,夜里是暖黑的台灯,而你随时可以自己拨动那盏灯。

工具都在变,从 Hexo 到 Astro,从框架到无框架。但「让文字被好好地读」这件事,不会变。