今天对友链页做了一次比较大的改造,主要做了三件事:删掉本站信息模块、在申请方法和友链列表之间塞进一个好友申请窗、然后把这个申请板做成信封的样子。
删掉本站信息
友链页原来顶部有一块"本站信息",放着博客名称、链接、头像、描述之类的信息。想了想,这些内容在侧边栏和关于页已经有了,友链页放这个有点多余,干脆删掉,让页面整体上移,打开就能看到申请方法和友链列表,更直接。
好友申请窗的需求
友链页有两个功能:一个是告诉别人怎么申请友链,另一个是展示已有的友链。但我之前一直缺少一个访客能直接申请的入口。原来的设计是让访客发邮件申请,但邮件这种东西,门槛还是偏高而且麻烦。
所以在申请方法和友链列表之间加了一个好友申请窗,让访客可以直接在页面里申请,不用跳转到邮箱客户端。
发送方式选了 FormSubmit,一个免费的服务,不需要后端,只要在表单里指定 action 地址就能把内容转发到邮箱。配置也很简单,几个 hidden 字段搞定邮件标题、跳转地址和人机验证开关。
信封效果
申请板做出来之后,觉得一个普通的表单太无聊了,想给它加点仪式感。既然是"给我写信",那就真的做成一封信的样子吧。
信封的外观
信封用了粉色渐变底色,和主题色统一。表面加了一层细横线纹理模拟磨皮质感,边缘有一圈虚线装饰。信封盖是上半部分的三角形区域,用 border-radius: 0 0 50% 50% 做出来的弧形。
火漆印用了主题自带的像素图标,设置了 image-rendering: pixelated 保持像素风不模糊。图标周围加了一圈粉色光晕和几颗小星星,用 CSS radial-gradient 画的,配合呼吸式缩放和闪烁动画。
打开逻辑
点击信封任意位置都能打开(输入框和按钮区域除外,不然没法填内容)。打开时信封盖向上翻转,信纸从信封里滑出来,用的是 transform: translateY 加弹性缓动。
信纸默认 pointer-events: none,打开后才变成可交互状态,防止信纸还没出来的时候就被点到。
寄出动画
点击"寄出信件"后,整个流程是这样的:
信纸先向下滑出消失,然后信封盖合回来,火漆印旋转着重新出现,最后显示"信件已寄出"。动画播放 1.5 秒后,表单自动提交到 FormSubmit,在新标签页打开确认页。
暗色模式
暗色模式下信封改为深粉色调,纹理透明度降低到几乎不可见,避免白色条纹在深色背景上太突兀。光晕和星星的透明度也做了对应调整。
踩的坑
暗色模式的选择器折腾了几轮。一开始用 html[data-theme="dark"],发现样式没生效;后来加了 .dark 类选择器,还是不行;最后试了在信封容器上用 JS 动态切换类名,配合 MutationObserver 监听主题变化,总算解决了。不过后来发现其实 html[data-theme="dark"] 就够了,之前不生效可能是选择器优先级被其他样式覆盖了,加上 !important 之后就好了。
信封的点击范围也改了几次。最初只有提示文字能点击,后来改成整个信封都能点,但要注意排除输入框、文本域和按钮的点击事件,不然填到一半信封就关了。
火漆印的特效残留也是个问题。图标太小的时候,周围的光晕和星星会露在图标外面,看起来像图标周围有一圈不明所以的光点。把图标从 36px 放大到 56px 之后,覆盖范围大了很多,残留就不明显了。
最终效果
友链页现在打开后,顶部是申请方法,中间是一封粉色信封,点击打开后可以填写昵称、邮箱和留言内容,点击寄出后信封会合上并提交表单。底部是友链列表。
整体改动不算复杂,但把 CSS 伪元素动画、3D 翻转、弹性缓动、暗色模式适配和表单提交都串在一起,算是一次比较完整的前端小项目。