网页上和「时间」有关的组件,看起来是一类东西,做起来完全不是。
一个挂在页面角落的时钟,它的任务是好看——没人真靠网页看时间,手机就在手边。一个活动倒计时的任务是制造紧迫感,它必须算得准,算错了就是事故。一条公司发展历程的时间轴,任务是把先后关系讲清楚,它根本不关心「现在几点」。而一个日期选择器,任务是让用户少输错一次,它是表单控件,属于另一个世界。
装饰、计时、叙事、输入——四件事,四种技术路线,四套评判标准。拿评价时钟的眼光去挑日期选择器,或者用做时间轴的思路去做倒计时,都会选偏。下面 16 款按这四类分开,每一类先说清楚这类组件真正该被怎么衡量。
一、时钟:装饰位上的时间(01 - 05)
时钟是这四类里最不讲功能的一类。它出现在个人主页、极客风仪表盘、活动页的角落,读的是本机时间,正确性几乎不用操心。它唯一的考核标准是「有没有意思」——如果一个网页时钟只是把手机上那串数字换个字体重画一遍,那它没有存在的必要。
01. 翻页数字时钟
CSS + JS
翻页时钟是机械时代留下来的形态,数字像日历一样翻过去。这一款的实现思路很直白:每个时间单位(时/分/秒)是一个容器,里面同时放着 data-prev 和 data-next 两组数字,CSS 负责翻转动画,JS 只管把下一秒的值写进去。
结构简单意味着好改——想换成翻页显示日期、显示倒计时天数,改的只是写进去的值,动画那一层原封不动。
02. 算盘时钟
CSS + JS
用打算盘的方式记时间:上半部分一颗珠子代表 5,下半部分一颗代表 1,时分秒各占一档。要看懂它,你得先懂算盘。
这是本文最「劝退」的一款,也是最有话题性的一款——它默认读者愿意花十秒钟破译一次。放在个人博客或者工具站的关于页上很合适,放在企业官网首页会有一半访客根本没看出那是时钟。
03. 三辆小火车绕圈跑的模拟时钟
SVG + JS
把三根指针换成三辆在圆形轨道上跑的小火车,速度差就是时分秒的差。SVG 画轨道和车,JS 驱动位置。
它的应用场景比看上去实在:儿童教育类页面——小孩理解「快的那根跑一圈,慢的那根才动一格」比理解指针容易;还有需要降低时间感知压力的地方,比如加载等候页。同样是让人干等,看一根秒针一格一格跳会觉得慢,看小火车绕圈会觉得快,这是很老的心理学把戏,但确实管用。
04. 可拖拽 360 度查看的 3D 模拟时钟
Three.js
不同于常见的 CSS 二维时钟,这一款用 Three.js 建了一个真正的三维钟面,有光影、有立体感,可以拖着转一圈看细节,指针随时间走。
代价是要引 Three.js。如果页面上只有这一个 3D 元素,为它单独加载一整个 3D 引擎不太划算——这类组件更适合放在已经在用 Three.js 的站点里,或者当作学习三维图形编程的样例来读。
05. 液态玻璃质感的实时数字时钟
SVG 滤镜 + 遮罩 webm 视频背景
数字带流体扭曲的质感,像一层会流动的玻璃盖在上面。做法是 SVG 滤镜叠遮罩,背景配 webm 视频素材,视觉冲击是这一组里最强的。
但它有一条明确的限制:目前只有 Chromium 系浏览器能完整呈现这个液态滤镜的质感。Safari 和 Firefox 上会退化。所以它适合的是内部大屏、演示页、创意倒计时页这种你能控制浏览器的场合;面向公众的官网首页就别放了,一半访客看到的会是另一个东西。
二、倒计时与秒表:时间有终点的那一类(06 - 09)
这一类和时钟的根本区别是:它会错。倒计时算错一秒没人在意,但如果用 setInterval 每秒加一,页面切到后台再切回来就会漂移,跑上几小时能差出十几秒。秒表更敏感,用户会盯着毫秒位看抖不抖。所以挑这一类要多看一眼实现方式。
06. 颗粒感红色闪烁数字倒计时
GSAP + CSS + SVG + Canvas
四种技术叠在一起做一件事:让剩下的天时分秒看着吓人。带颗粒感的红色荧光数字在闪,压迫感很足,原本是给万圣节主题做的。
它的用法不限于节日。限时抢购、报名截止、拍卖结束这些场景要的就是这种紧张感,把配色从红换成品牌色就能直接用。要注意的是四个库堆在一起体积不小,别放在需要抢首屏速度的页面上。
07. 纯 CSS 大屏倒计时
纯 CSS
上一款的反面:大屏用十字线分成四格,中间是圆形数字,翻转和渐变都靠 CSS 过渡完成,克制得多。
「纯 CSS」在这里既是优点也是边界——动画那一层零依赖、零脚本开销,但数字更新终究要有人去写。它适合活动预告页、展厅大屏这类版面大、看得远的场合,也适合当作一层动画外壳,把你自己算好的时间套进去。
08. 拟物秒表:用 performance.now() 而不是 Date.now()
CSS + JS performance.now() 分圈计时
圆盘表盘配进度弧线,拟物质感做得细,开始/暂停按钮的颜色实时切换,支持分圈记录。UI 很克制,没有多余装饰。
这一款值得展开说的是它的计时方式:用 performance.now() 替代 Date.now(),配合 requestAnimationFrame 驱动渲染。按 MDN 的文档,两者的差别是实打实的:
Date.now()只有毫秒级整数分辨率,而performance.now()是浮点数,理论上可到微秒级;Date.now()取自系统时钟,会被系统时间调整、时钟偏移影响;performance.now()走的是单调时钟,改系统时间也不会跳;出于 Spectre 类攻击的防护,浏览器会主动降低
performance.now()的精度:跨源隔离环境下钳制到 5 微秒,非隔离环境下钳制到 100 微秒——仍然远好于 1 毫秒。
所以毫秒位不抖不是玄学,是选对了 API。运动计时、在线考试计时、专注训练类工具,都该照这个做法来。
09. 带音效的鸡蛋壳计时器
SVG + CSS + JS 场景音效
SVG 画出蛋形刻度条,蛋壳中间同步显示环形进度,点开始会发出急促的滴答声,归零触发闹钟音效。
这是本文唯一一款带声音的。声音在网页上是个双刃货——用对场景很加分,用错就是骚扰。它对的场景很明确:美食教程页面的分步计时、智能厨房设备的网页控制面板,这些地方用户的手上正忙着,眼睛不一定在屏幕上,声音反而是唯一能传达信息的通道。
三、时间轴:把一串事件排出先后(10 - 13)
时间轴根本不显示「现在」,它显示的是「顺序」。企业发展历程、产品迭代记录、项目里程碑、教学步骤,都是它的活。这一类的挑选标准是长内容怎么办——三个节点谁做都好看,二十个节点还能不能读下去,才是分水岭。
10. CSS Grid 排期表:零 JavaScript 的甘特式日程
纯 CSS Grid subgrid @layer OKLCH
按半小时刻度排的横向日程表,表头从 07:30 到 17:00 共 20 个时间格,下面每一行是一个人或一项资源,彩色块标出任务的起止和时长。全部由 CSS Grid 实现,零 JavaScript。
几个做法很值得抄:
加一个任务只写两个数字——起始列和结束列,位置和宽度自动算好;
表头和内容永远对齐,靠
subgrid继承父级的列轨道,缩放时不会错位;整块色卡只由一个 data 属性决定,填充色、边框色、文字色一起变;
样式用
@layer分层组织,配色用oklch()定义。
这三个较新的特性今天都能放心用了。caniuse.com 给出的数据:subgrid 全球支持率 93.48%(Chrome/Edge 117、Safari 16.0、Firefox 71 起);级联层 @layer 支持率 96.03%(Chrome/Edge 99、Safari 15.4、Firefox 97 起);oklch() 支持率 94.25%(Safari 15.4 最早,Chrome/Edge 111、Firefox 113 跟上)。要兼容 IE 的项目不必考虑这一款,其余情况直接用。
11. 随滚动弯曲的事件轨迹
Scroll-Animation API + CSS
轨迹线随着页面滚动弯曲延伸,两侧的图文区块分层入场。它把时间轴从「一条竖线加几个点」变成了一段有节奏的滚动叙事。
适合公司发展历程、产品演进史这种需要被慢慢读完的内容——弯曲的线条本身就在暗示「还没结束,接着往下」。用在只有四五个节点的短内容上会显得用力过猛。
12. 可折叠时间轴:长内容的解法
CSS + Bootstrap 5 折叠面板
核心理念是「按需展示」:把长篇的流程、教学步骤或历史事件压缩成一条竖线,每个节点用折叠面板收起详细内容,用户点开哪个看哪个。
这是本文回答「节点太多怎么办」最直接的一款。二十个节点全展开,页面会长到没人愿意滚;全收起来只留标题,一屏就能看完整条线的骨架,想细看再展开。基于 Bootstrap 5 的折叠组件做,已经在用 Bootstrap 的项目接进去几乎没有额外成本。
13. 可左右拉伸的水平时间轴
CSS + JS 水平方向
事件沿水平方向排开,可以无限左右拉伸,每个节点带图标、日期和描述,点节点或者点两侧的导航按钮切换。
横向和纵向的选择不只是审美:纵向跟着页面滚动走,适合夹在长图文中间;横向自成一块,适合放在首页或者关于页当作一个独立展示区。横向的代价是移动端更难处理,这一款靠导航按钮解决——手机上不指望用户去横向拖,给两个箭头逐条翻。
四、日期与时间选择器:这一类是表单控件(14 - 16)
前面三类都是「展示」,这一类是「输入」,评判标准完全换了一套:能不能用键盘操作、在手机上点不点得中、选错了好不好改、值能不能顺利提交进表单。创意在这里是次要的,好用才是第一位。挑的时候一定要在手机上试一遍。
14. 轮盘拨号式日期选择器
SVG + JS + CSS
鼠标移到日期数字上拖动,会浮出一个复古的圆盘拨号器,拖着圆盘拨年、月、日,三项联动变化。
这一款的取舍很明确:用操作乐趣换操作精度。拨盘选「明天」比日历慢,但选「1987 年 3 月」比在日历上点二十次上一月快得多。所以它适合的是需要跨大范围选年份的场景——生日、入职时间、历史资料筛选;订房订场这种只在最近两周里选的,还是老老实实用日历。
15. 弧形时间滑块
SVG + CSS + JS 触摸优先
SVG 画一条可拖拽的弧形刻度盘,滑动手柄时进度条填色变化,实时显示对应时间值,触摸和鼠标都支持。
它解决的是一个很具体的问题:选「几点」和选「哪一天」是两回事。日历控件擅长后者,前者用下拉框选 24 个小时既慢又丑。弧形滑块把一天摊成一段弧,拇指一划就到,在手机上尤其顺手。预约系统里选到店时段、运动计时设定时长、冥想应用设定分钟数,都是它的场子。
16. React 极简中文月历:168 行,零第三方依赖
React 18 UMD 168 行 零依赖
顶部一行年份、月份和左右翻月箭头,点年份或月份文字直接跳回今天;下面 7 列网格排星期缩写和整月日期,今天用高亮圆点标记,跨月补齐的日期灰显不可选。
它整份脚本只有 168 行,用 React 18 的 UMD 构建加原生 Date 对象写成,没有引 date-fns、也没有引 dayjs,可以直接扔进任何用 CDN 引 React 的静态页里跑。里面有个小技巧值得记:给 new Date(year, month, 0).getDate() 传第 0 天等价于「上个月的最后一天」,一句话就拿到了当月天数,不需要判断闰年、也不需要日期库。年月状态全靠 useState 加 useMemo 管理。
适合当业务日历、预约系统、活动打卡的基础壳——先用它跑通逻辑,真需要区间选择和禁用日期时再往上加。
一张表对号入座
| 你要做的事 | 属于哪一类 | 可以直接看 |
|---|---|---|
| 个人主页 / 极客仪表盘想放个有意思的时钟 | 装饰 | 01 翻页、02 算盘、04 3D |
| 儿童教育页、加载等候页想弱化「等待感」 | 装饰 | 03 小火车 |
| 内部大屏、演示页要视觉冲击(浏览器可控) | 装饰 | 05 液态玻璃 |
| 限时抢购、报名截止要制造紧迫感 | 计时 | 06 红色闪烁倒计时 |
| 活动预告、展厅大屏,克制一点 | 计时 | 07 纯 CSS 大屏倒计时 |
| 运动计时、考试计时,毫秒不能抖 | 计时 | 08 拟物秒表 |
| 教程分步计时,用户眼睛不在屏幕上 | 计时 | 09 鸡蛋计时器 |
| 排班表、会议室占用、项目甘特图 | 叙事 | 10 CSS Grid 排期表 |
| 公司历程、产品演进,要慢慢读完 | 叙事 | 11 滚动弯曲轨迹 |
| 节点超过十几个,怕页面太长 | 叙事 | 12 可折叠时间轴 |
| 首页 / 关于页要一块独立展示区 | 叙事 | 13 水平时间轴 |
| 生日、入职日期,要跨很多年选 | 输入 | 14 轮盘拨号 |
| 只选「几点」,手机上要好点 | 输入 | 15 弧形时间滑块 |
| React 项目要个日历壳子,不想加依赖 | 输入 | 16 React 月历 |
最后提醒一件容易忽略的事:装饰类和输入类的时间组件,可访问性要求完全不同。一个纯装饰的时钟,屏幕阅读器读不读得出来无所谓,甚至该用 aria-hidden 藏起来免得干扰;而日期选择器是表单的一部分,标签、格式提示、键盘操作一个都不能少。上线前照这条分一次类,能省掉后面很多返工。
本文的 16 款都在童哲网网页特效板块。相关的几篇:表单与登录界面效果(日期选择器的邻居们)、加载动画与进度条效果(和倒计时同属「让等待变短」)、卡片与布局效果(时间轴节点的排版参考)、CSS 按钮与开关交互效果(秒表的开始暂停按钮可以从这里挑)。



























