QUIET READING
把阅读控制权交还给读者
字号、行宽、沉浸开关与系统偏好如何共同构成长文阅读界面。

minimal 不是视觉奖章,而是一项维护承诺:这篇文章仍以阅读为主,但不需要完整导航和页脚。页面只保留返回桥、正文与必要阅读控制。
行宽先于字号
中文长文把默认阅读宽度控制在约 40 个全角字。字号变化时,容器仍按相对单位回流,而不是保持固定像素宽度。
运行时沉浸不等于构建时档位
文章的 chrome 是作者在构建时声明的页面性质;沉浸开关则是读者在运行时临时收起界面。前者决定页面生来是什么,后者只改变这一刻的阅读状态。
偏好必须可恢复
字号和沉浸状态只保存在本地浏览器。所有值先规范化为有限范围,再写入 CSS 变量或 data-* 属性,避免无界状态污染布局。
控件不是漂浮的装饰
阅读控件只有在它改变阅读条件时才有存在理由。字号按钮必须更新正文的排版变量,沉浸按钮必须真正收起导航干扰,键盘焦点与 aria-pressed 也必须同步。若一枚图标只有悬停动画,却没有可验证的状态变化,它就不属于阅读工具。
用约束避免布局雪崩
正文宽度、标题字号和代码块溢出是同一个响应式问题。实现上让行宽使用 ch 与视口上限共同约束,让标题通过 clamp() 缩放,并允许代码区横向滚动。这样字号从 90% 调到 120% 时,不需要为每个断点另写一套页面。
验收一项真实偏好
每次改动至少检查三条路径:无本地记录时服从系统偏好;刷新后恢复读者设置;开启减少动态效果时停止非必要动画。所谓“把控制权交还给读者”,最后应当能够被浏览器自动化和人工键盘操作共同证明。
三种状态不能混在一个布尔值里
当前实现把字号、行距和沉浸分别保存。字号是连续但有上下界的尺度,行距只允许紧凑、标准、舒展三个离散值,沉浸则是临时界面状态。若把它们压进一个“阅读模式”开关,读者只想放大文字时也会被迫接受隐藏导航或改变行距;后续增加高对比度选项时,组合数还会迅速失控。
页面初始化也有顺序要求。首屏绘制前先读取主题与可安全恢复的排版偏好,避免正文先以默认字号出现、随后跳动;组件挂载后再绑定按钮和键盘事件,避免内联脚本承担完整应用状态。无效的旧值直接回到默认值,而不是让 NaN 或任意字符串进入 CSS 自定义属性。
中文阅读宽度需要在真实字体中判断
40em 只是工程近似,不是美学定理。不同中文字体的全角字宽、标点挤压和英数混排差异明显,代码块、表格、引用也会改变一屏的密度。因此验收不能只看容器计算值,还要在宋体阅读正文、系统 UI 字体元数据和等宽代码三种材料交界处检查节奏。
本站把正文保持为较窄的稳定列,却允许图、表和交互组件通过 media-wide 或 media-bleed 离开文字列。这样“易读的行长”和“足够大的证据图”不再互相牺牲;移动端则自动收回浮动与越界,避免把桌面编排机械缩小。
控制权也包括“不被记住”
这些偏好没有必要进入账号或服务端分析。它们只写入当前浏览器,本地存储不可用时页面仍能工作;清除站点数据即可恢复默认。站点不根据阅读速度推断兴趣,也不把沉浸状态当成参与度指标。对个人博客而言,尊重阅读者的最低成本方案往往不是建立一套偏好云,而是让本地偏好足够可靠、足够容易撤销。
本文采用 CC BY-NC-SA 4.0 许可;转载时请保留作者与原文链接。