最近给博客换上了一套新主题,名字叫 LumaGlass,澄光。

起点是 Sandro 的 TypechoGlass。我很喜欢它想表达的玻璃、高斯模糊和亮暗模式,也希望在这个方向上继续打磨,让版式、材质和阅读体验更符合自己的偏好。最开始的改动只涉及页脚,后来逐渐变成了一个独立主题。

这次开发由我提出方向、检查效果并调整取舍,Codex 协助实现代码和验证页面。把过程记下来,既是介绍这个主题,也给以后继续修改留一点依据。

原主题已经具备文章和独立页面的模板,分类与搜索、归档和友链也有模板,还有主题设置、文章字段和插件接口。它给了这次开发一个完整的基础。

LumaGlass 因此保留了 PHP 模板、CSS 和原生 JavaScript 的结构。文章数据仍由 Typecho 管理,安装后就能使用,也不需要额外的前端构建流程。原有的封面、副标题和推荐标记字段继续保留,关闭目录字段也保留了。

主题的上游来源与 GPL-3.0 许可也保留在仓库中。对我来说,这次 fork 是沿着一个喜欢的方向继续做下去。

最先确定的是材质:界面要能看出背景的光与颜色,同时让内容容易辨认。

如果每张卡片都采用同样的透明度和模糊强度,整个页面容易变成一堆彼此竞争的半透明方框。这一版因此把玻璃分成了几个层次。

  • 导航栏用较轻的玻璃材质,滚动时仍能感受到下面的内容。
  • 个人空间与侧栏有更明显的轮廓和层次,承担状态、简介等辅助信息。
  • 文章列表与正文使用更厚、更不透明的底色,把文字对比度放在前面。

高光边缘、内阴影和柔和的外阴影共同构成材质的厚度。高斯模糊只是其中一部分,还需要配合背景颜色、透明度与边界。

例如,导航材质的写法可以概括为:

.glass-chrome {
  background: rgba(255, 255, 255, .62);
  backdrop-filter: blur(26px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, .85);
}

背景采用雾蓝、浅紫和静态的层叠形状,为玻璃提供可以透出的颜色。深色模式重新定义背景和文字,以及边缘与阴影,使它在夜间也有自己的层次。截图中如果出现飘落效果,那来自独立的四季插件,主题本身的背景保持静止。

LumaGlass 浅色模式下的悬浮导航和个人空间卡片

浅色首页局部预览:用背景色差和不同厚度的面板建立层次。

首页保留了站点标题和介绍,阅读入口也保留了,还有一个包含状态与天气的个人空间卡片。文章区域则改为更清楚的列表,让封面与标题,以及摘要和时间形成稳定的阅读顺序。

进入文章后,装饰进一步收敛。标题和发布信息位于正文之前,正文使用较厚的阅读面板;桌面端的目录放在侧边,窄屏下移到正文前面。这样既能快速了解文章结构,也能保留完整的正文宽度。

字体优先使用系统字体。大标题适当收紧字距,正文则保留舒适的行距。中文、长标题和无法自然断行的英文,都需要在窄屏上重新检查。

这次也顺手修正了一个继承来的问题:没有搜索结果时,标题逻辑会尝试读取不存在的文章字段。空结果页现在可以正常展示,并提供继续浏览的入口。归档页则按年份组织具体文章,能直接进入对应的记录。

LumaGlass 深色模式下的首页玻璃材质

深色首页局部预览:保留材质层次,同时提高文字与背景的区分度。

这次参考了苹果关于流畅界面的设计思路。对我影响比较直接的,是及时响应和允许中途改变操作,也包括保持动作的连续性;可以从苹果的 Designing Fluid Interfaces 演讲进一步了解这些原则。

落实到博客里,主要是一些很小的细节:按钮按下时立即反馈;搜索面板打开后聚焦输入框;按 Esc 可以关闭;关闭后焦点回到触发按钮;桌面端可以用 ⌘ / Ctrl + K 呼出搜索。

搜索的过渡采用浏览器原生动画,并允许在关闭过程中重新打开,从当前呈现状态继续。移动导航关闭时,隐藏的链接不会继续参与键盘焦点顺序。

颜色模式支持浅色、深色和跟随系统,并记住访客的选择。天气按地点缓存半小时,请求失败时优先保留已有数据。对于读取不了浏览器存储、图片加载失败等情况,也补上了降级处理。

这些细节很少成为截图的主角,却会影响一个页面是否用得顺手。

开发中最值得记下来的一次纠正,是配置边界。

一开始,为了保留本站原有的页脚,我把具体备案信息留成了主题默认值。准备公开仓库之后,这个做法就显得不合适:主题会被别人安装,而每个站点应该填写自己的信息。

现在,ICP备案号、公安备案号、查询链接和图标都通过 Typecho 的主题设置管理。备案号默认留空;没有填写时隐藏,未填写链接时显示纯文字,未填写图标时不显示图片。已有的站点配置继续保存在数据库中。

首页附注、侧栏短句和页脚文案也改为后台填写,留空就隐藏。主题负责决定这些信息如何呈现,具体内容交给站点管理员。

这件事也提醒了我:把个人定制公开成一个可复用的主题时,除了检查页面效果,还要检查源码和提交历史里是否带入了属于某一个站点的默认资料。这一轮也重新整理了相关开发提交。

开发时使用了独立数据库副本做预览,先把页面跑起来,再逐项检查。

这一轮覆盖了首页和文章,独立页面也检查过,分类与搜索、归档和友链都在范围内,还包括 404 和 RSS。目录跳转和评论回复检查过,搜索焦点与颜色模式保存也检查了;布局则检查了 320、390、768、1440 像素这几种宽度。

普通内容之外,还试了很长的标题和连续英文,空博客与分页也试过,还检查了失效图片和不可用的浏览器存储,关闭 JavaScript 的情况也试了。长文本测试确实找到了窄屏溢出,随后补上了换行处理。

减少动画、减少透明度和增强对比度的偏好也纳入了样式适配。备案与附注文案则有单独的回归检查,确认空默认值和留空隐藏,也确认文本转义以及已填写内容的显示行为。

这些验证主要来自浏览器自动化和不同视口下的检查。真实手机上的触控感受,以及内容量增加后的长期表现,仍值得继续观察。

主题已经放在 LianjinSe/LumaGlass,默认开发分支为 lumaglass。

可以克隆后放入 Typecho 的 usr/themes/ 目录:

git clone https://github.com/LianjinSe/LumaGlass.git LumaGlass

然后在后台启用 LumaGlass,检查首页文案、Logo、背景、社交链接与备案设置。归档和友链页面分别选择对应的独立页面模板即可。

感谢 TypechoGlass 提供的基础。这次开发让我更在意界面里那些不显眼的关系,包括透明度与文字、装饰与留白,也包括动作与反馈,以及主题代码与站点内容之间的边界。

LumaGlass 先作为这一轮尝试留在博客里。接下来,就用真实的文章和日常访问,慢慢检验它。