lzwcc/ ui-motion-lab
No.001 · UI · 2026.10.05刷到自 seg6.space
作品 / UI

纸张滚动效果

文字在纸上流动,纸张的边缘与阴影保持原位。

复刻css

把鼠标放在下面的纸张里滚动,或在触屏上滑动。留意纸张上下边缘:文字经过,边框和阴影停留。

Demo · 动手试试
lzwccwritingexperiments

oct 5, 2026

让阅读回到一张纸上

内容在移动,阅读的边界留在原处。

把鼠标放在这张纸上,向下滚动。文字会缓缓向上移动,而纸张四周的留白和阴影仍停在原处。触屏上可以直接在纸张里滑动。

灰色像桌面,米白色像纸。没有翻页,也没有复杂的运动,只是让阅读发生在一个安静、稳定的窗口里。

边缘留下,内容经过

观察上方和下方的边缘:文字接近边界时,逐渐从纸张窗口中离开。灰色遮罩盖住了外侧的内容,让纸看起来始终保持同样的大小。

真正滚动的是一篇很长的文章。覆盖在文章上方的边框、阴影和遮罩使用 sticky 定位,随着滚动保持在阅读窗口的位置。

少一点动作,多一点质感

纸张的质感来自几处很小的差异:微暖的底色、细细的边框、贴近边缘的一层阴影,以及更远、更柔和的一层阴影。

正文留出足够的行距,版心稍微收窄。即使没有图片,这些细节也能让一段普通的文字拥有自己的空间。

回到页面,继续阅读

这个实验被收在文章里的独立滚动区域中。滚动到这里,纸张的外框仍在原处,你也可以向上滚动,再看一次文字经过边缘的过程。

试试站点导航上的主题按钮。纸张、桌面和目录会一起切换配色,切换后会记住你的选择。

✻你已经读到了这张纸的最后。

这个演示有自己的滚动区域。你也可以点击纸张后,用方向键或 Page Down 阅读;切换导航上的主题按钮,可以查看深色效果。

灵感来自 seg6.space,使用 Vue 组件与局部 CSS 实现。

提示词

复制给 Claude、ChatGPT 或编码 agent,可以复现本页的纸张窗口。

做一个「纸张滚动」阅读窗口:固定高度的区域里有一张纸,滚动时文字在纸上经过,纸的边框、阴影和四周的桌面留白停在原处。只用 HTML 和 CSS,目录高亮用少量 JS。

1. 外层滚动容器:高度 clamp(420px, 65svh, 620px),overflow: auto,overscroll-behavior: contain,内边距 16px(记为 --gap),背景是桌面色,隐藏滚动条,isolation: isolate,加 tabindex="0" 让键盘也能滚动。
2. 容器里是一篇很长的文章,这才是真正滚动的内容。它的最小高度 = 容器高度 − 2 × 16px(记为纸张高度)。背景用横向线性渐变画出纸:两侧各 --side 宽是桌面色(大屏 120px,小屏 0),中间是纸色。
3. 文章最前面放一个装饰层:position: sticky; top: 0; z-index: 2;高度等于纸张高度,margin-bottom 取负的纸张高度,让它不占文档流;pointer-events: none。装饰层里有两样东西:
   - 遮罩:一个 3×3 网格,向外扩出 16px 盖住容器内边距,铺满整个容器。上、下两条和左、右两块填桌面色,中间格留空。文字滚到纸外时被它盖住。
   - 纸框:position: absolute; inset: 0 var(--side);1px 边框 rgb(20 20 16 / 8%);阴影 0 1px 2px rgb(20 20 16 / 8%), 0 14px 35px rgb(20 20 16 / 18%)。
4. 配色:浅色模式桌面 #cacac6、纸 #fffefb、文字 #10100f;深色模式桌面 #111210、纸 #1b1c19、文字 #e9e7df。正文用衬线体(Georgia, "Songti SC", serif),字号 14px,行高 1.85,版心最宽 720px,左右内边距 28px。
5. 目录(可选):大屏放在右侧 --side 栏里,sticky 置顶。滚动时把容器顶部往下 100px 当作阅读线,最后一个越过阅读线的章节标题高亮;滚到底时直接高亮最后一章。点击目录平滑滚动到对应章节,prefers-reduced-motion 时直接跳转。