动态页「星河」重设计:把时间线变成一条河
起点
博客动态页最初就是一列暗色直线时间线,卡片全在右侧,亮暗切换几乎无感。回头看,那个"亮色"其实就是深海军蓝——亮了个寂寞。
想改。两条线并行:一是做一个真正的亮色模式(暖纸、晨光、书卷气),二是打破直线排列,让布局本身有张力。
核心隐喻:星河
名字定了叫「星河」(Star River)——一条蜿蜒的光之河流,每条动态是河中的一颗星。切换主题时呈现两种面貌:
| 晨光轨迹(亮色) | 星河暗涌(暗色) | |
|---|---|---|
| 底色 | 暖纸色渐变 | 深海军蓝 |
| 光轨 | 金色光束 | 琥珀→紫→青渐变光柱 |
| 卡片 | 白纸 + 暖色阴影 | 毛玻璃 + 发光边框 |
| 氛围 | 金色微尘、暖色光晕 | 白色星点、彩色光球 |
| 徽章 | 柔粉/淡紫/浅蓝 pastel | 发光琥珀/紫/青 |
布局:交替河流
桌面端,光轨居中(left: 50%),卡片 width: calc(50% - 2.5rem)。奇数卡 margin-left: auto 推到右侧,偶数卡留在左侧。每张卡片 ±2° 随机微旋转(CSS 变量 --card-rot,8 个角度循环),入场动画带着微倾淡入。卡片与光轨之间用 ::before/::after 画弯曲短弧连接,圆点延伸出卡片 wrapper、定位在光轨正上方。
移动端光轨移到左侧,所有卡片单列排列,取消旋转和弧线。
纯 CSS 背景系统
五层叠加,零图片:
activity-bg(z-0):渐变底色activity-breathe(z-[1]):双色椭圆光晕呼吸层,8s 脉动activity-specks(z-[2]):radial-gradient手搓微粒——亮色暖金微尘 10 颗,暗色白色星点 15 颗activity-overlay(z-[2]):渐变蒙层 +backdrop-blur(1px)activity-glow-*(z-[2]):光晕装饰球,亮色 2 球/暗色 3 球,blur(60-80px)+activity-glow-drift漂移动画
一些踩坑
animation-fill-mode 的坑。 卡片入场动画如果设 forwards,动画结束后 opacity: 1 保留——但旋转也被保留在最终 keyframe 的 rotate() 值。用 backwards:动画开始前元素停留在 from 帧,动画结束后释放,opacity 回到自然值(1),rotate 也由 CSS 变量正常控制。
Tailwind tree-shaking。 圆点颜色类(activity-dot-amber 等)在 globals.css 中定义,但只在 className 动态拼接中出现。Tailwind 的 JIT 扫不到——需要用 bg-[#e09070] 内联写法,或者在 tailwind.config.js 的 safelist 中注册。最终选择了纯 CSS 自定义类,完全不走 Tailwind。
光轨和日期的叠加。 月份标签最初是 text-align: center 直接放在光轨上,文字和光束硬叠,很丑。改成 flexbox 胶囊:::before 和 ::after 画装饰线,中间 <span> 用实色背景遮住光轨——像个悬浮的日期封条。
Header 的亮色适配。 动态页亮色背景是暖纸色,Header 原来透明模式下强制白字 + textShadow,在亮色背景上直接糊掉。给 Header 加了 isLightActivity 判断:activity 页 + 亮色模式时,透明 Header 用深色文字 #5a4030、半透白渐变背景。
设计原则
这个页面让我体会到,静态博客的设计可以很重——因为没有后端,所有视觉计算都在构建时完成。这意味着你可以大胆地用 CSS 堆效果,不用考虑运行时性能(浏览器处理纯 CSS 很快)。但也意味着每个像素都要自己想清楚,因为没有现成的组件库替你决定间距、阴影、动效。