feat/pr-9 这一批改动来自贡献者 jinghuashang 的 PR #9。功能设计是他的,最终重新实现了一些功能,调整了一些不兼容的配置。
一共六项:堆叠相册、渐进式开屏大图、窄屏独立背景图、打字机、滚动渐入、页脚图标链接与署名位置。其中两项可以直接在文章里演示,剩下四项是站点级的——这个页面本身就在跑,往下翻的时候留意一下页脚和回到首页的开屏。
堆叠相册
引入了 {% stackalbum 480,480 %} 标签:
一叠像扑克牌一样码在一起的照片。点最上面那张,它会被抽起来,然后滑到牌堆最底下。




写法就是一个标签包一组普通的 markdown 图片:
1 | {% stackalbum 480,480 %} |
几个细节:
- 参数
宽,高可选,默认480,480。 - markdown 的 title 位置填
"h"是横卡(480×320),"v"是竖卡(320×480)。不填的按图片自己的宽高比在浏览器端判断——上面第四张就没填。 - 容器高度按卡片实际占位算,取「
高参数」和「卡片真正需要的空间」里较大的那个。所以竖图多、张数多的时候不会溢出到下面的正文里。 - 窄屏会整体缩放到放得下为止。缩放看的是牌堆实际有多少地方可用,不是某个像素断点——所以窄侧栏、平板分栏和手机是同一套逻辑。
- 键盘可用:牌堆本身可以聚焦,
Enter或→翻到下一张。堆叠状态下只有最上层是清晰的,不给键盘路径的话其余照片对不用鼠标的人就是不存在的。Space有意没绑——它是翻页键。
主题的 Fancybox 灯箱会自动包裹正文图片,但相册里的图片带了 no-zoom,所以点击只翻牌、不会弹出大图。
悬停翻牌
引入了 {% stackalbumnav %} 标签:
小一号的变体,一个牌堆配一列名字。鼠标移到名字上(或者用 Tab 键聚焦),对应的封面会翻到最上层;移开就恢复原来的顺序。
标签的参数是一条数据路径:
1 | {% stackalbumnav collections.anime %} |
第一段是 source/_data/ 下的文件名,后面按点号往下钻,最终指到一个列表。这个例子读的是 source/_data/collections.yml:
1 | anime: |
文件名和键名都是你自己定的。
字段接别名:名字用 name 或 title,链接用 href / link / url,封面用 cover / image / src。
渐进式开屏大图
这项要回首页看。开启后开屏背景是这样加载的:先铺一张高斯模糊的小图占位,等背景大图解码完成再淡出交接;同时往下滚的时候图片会轻微放大、整个开屏渐隐。
1 | home_hero: |
关键在于图源仍然只有 image 一个。image_progressive 改变的是它怎么加载,不是换一个图源进来,所以 image_overlay、mobile_image、多图随机轮播全部照常生效。加载失败、脚本没跑、或者浏览器禁用 JS,都会直接显示 image 本身——模糊层带着 hidden 属性出场,由脚本揭开,两秒内没人接手就自己藏回去。
原 PR 那版滚动时还会逐帧加 blur()。 目前主题只保留了 opacity 和 transform。
窄屏可以单独指定一张
mobile_image 从开关变成了「开关或图源」:
1 | home_hero: |
填链接的时候,窄屏(≤760px)单独用那张图,适合另外准备一版竖版裁切。这时候开屏仍然是照片模式,文字和按钮配色不变——只有背景图那一条声明变了。
打字机
页脚版权行右边那一句,还有首页开屏 bio 的位置——这个站两处都开着,翻到本页最底下就能看到。
1 | footer: |
home_hero.typed 是同一套字段。两处同时开启也只会请求一次 Typed.js。
CDN 不可达的时候不会转圈:onerror 和 6 秒超时走同一个出口,退回纯文本显示 sub 第一行。hero 那一侧 sub 为空时会回退到 hero.bio / profile.bio,不会渲染出一个空段落。
滚动渐入
也是回首页看:精选轮播、章节标题、文章卡和侧栏卡进入视口时逐个上浮渐显,文章卡按位置交错出场。
值得说的是没有 JS 的时候会怎样。.reveal 的初始状态是 opacity: 0,如果就这么发出去,禁用 JS 的读者会看到一个空首页。所以隐藏这件事由 <head> 里的内联脚本决定:只有在 IntersectionObserver 存在时才给根元素加 reveal-ready,并且挂一个两秒的看门狗——main.js 没接上观察器的话就把这个类摘掉。没有 JS,就没有任何东西被隐藏过。
交错延迟走的是自定义属性 --reveal-delay 加 animation-delay,而不是内联 transition-delay。后者会顺带延迟卡片自己的 hover 抬升,每行靠后的卡片鼠标移上去要等最多 300ms 才有反应。
页脚图标链接与署名位置
看本页页脚右侧那一行:归档 · 分类 · 标签 · [CC 图标组] · Powered by Theme FlatPaper。
条目可以只有图标、没有文字:
1 | footer: |
icons 是数组,一个链接里可以并排几个图标。主题的图标按需打包机制同步认这个字段,所以只有真正用到的 SVG 才会进产物。纯图标链接没有可读的名字,aria-label 会补上。
主题署名的位置换了配置面:
1 | footer: |
first—— 并入第一组链接行的末尾,也就是这个站现在的样子last—— 并入最后一行末尾own—— 独占一行
默认布局变了。 v0.4.0 里署名是独占第一行的,现在默认并入第一组链接行。如果你配了 footer.links,升级后右侧会从两行变成一行。想要旧的样子就写 row: own。
为什么默认从「独占一行」改成「并入」:.site-footer__right 是一行一个 row 的 grid,配了备案信息的站点会得到
1 | Powered by Theme FlatPaper |
主次颠倒了——备案信息才是主体,主题署名压在它头上。
赞赏名单
在关于页一类的独立页面正文里写一段结构化 HTML,就能得到手账便签风格的赞赏卡片。没有新增配置项。
共 5 人 · 最新更新时间:
金额徽章的颜色不用自己写:脚本扫 .reward-list__amount 的文本,解析出数字后按人民币纸币面额自动上色——≥100 红、≥50 绿、≥20 棕黄、≥10 蓝、≥5 紫、≥1 橄榄绿。markup 里已经写了 reward-list__amount--50 这类档位类的话,以你写的为准。
纸色档位 --p1 到 --p5 循环使用,胶带颜色跟着纸色走。头像可以放 <img class="reward-list__avatar no-zoom"> 贴在右上角,也可以像上面这样用 .reward-list__avatar--text 显示名字首字。
1 | <div class="reward-list"> |
配置速查
| 功能 | 配置 / 写法 | 默认 |
|---|---|---|
| 堆叠相册 | {% stackalbum 宽,高 %} … {% endstackalbum %} |
—— |
| 悬停翻牌 | {% stackalbumnav 数据路径 %} |
—— |
| 渐进开屏 | home_hero.image_progressive / image_placeholder |
关 |
| 窄屏背景图 | home_hero.mobile_image(true / false / 链接) |
true |
| 打字机 | footer.typed / home_hero.typed |
关 |
| 滚动渐入 | 无配置项,首页自动生效 | 开 |
| 页脚图标 | footer.links[].icons / title / aria-label |
—— |
| 署名位置 | footer.powered.row |
first |
| 赞赏名单 | 正文写结构化 HTML | —— |
原 PR 里还有一项侧边栏定位欢迎卡片(按访客 IP 显示归属地和距离),最后决定不合并进主题。它需要把每个访客的 IP 发给第三方接口,可以通过外挂 JS 实现。

评论