必须用而非,因其天然语义化、支持屏幕阅读器读序号、便于精准选择当前项;主线用::before+position: relative定位,圆点用::after+top: 50%+transform translateY(-50%)垂直居中,确保内容变动时布局不崩。

直接用 套 ,主线画在容器上、圆点画在每个 上,别用 flex 或 grid 堆中轴线——这是最稳的竖向时间轴布局方式,改内容、加动画、切深色模式都不容易崩。
为什么必须用
而不是 套
语义对了,屏幕阅读器能读出“第1项、第2项”,datetime 属性也能被搜索引擎和无障碍工具识别;更重要的是,后续想加“当前进行中”状态,可以用 ol > li:nth-child(3) 精准命中,不用靠 class 切换或 JS 查找。常见错误是写成 ...,这种结构一加 hover 动画或 IntersectionObserver 就得反复改选择器。
::before 画主线时,position: absolute 必须配 position: relative 在父容器上
否则伪元素会相对于 定位,主线偏移、断开、随滚动错位全由此起。实操要点:
-
必须设 position: relative
-
.timeline::before 设 content: ""、position: absolute、left: 50%、transform: translateX(-50%)、width: 2px、height: 100%
- 漏掉
position: relative,或者把 transform 写成 translateY(-50%)(这是垂直居中圆点用的),主线就会歪到左边或消失
每个时间点的圆点必须用 ::after + top: 50%; transform: translateY(-50%)
不是 margin-top 推,也不是 line-height 挤,更不能用 vertical-align(它对块级元素无效)。关键原因:
-
内容高度不固定(比如文字换行),只有 top: 50% + translateY(-50%) 能保证圆点始终钉在整块内容的垂直中心
- 如果用了
margin-top: 20px,字体一变、行数一增,圆点就卡在第一行末尾,视觉上严重错位
-
必须设 position: relative,否则 ::after 的 top 会相对于
计算,导致所有圆点叠在一起
左右交替布局别用 float 或硬写 left/right,用 :nth-child(odd/even) 控制 padding 和 text-align
移动端缩放、字体加载延迟、RTL 语言(如阿拉伯语)都会让 float 失效或翻车。正确做法:
-
.timeline li:nth-child(odd) .timeline-content 设 text-align: right、padding-right: 80px
-
.timeline li:nth-child(even) .timeline-content 设 text-align: left、padding-left: 80px
- 圆点统一用
left: 50% + transform: translateX(-50%),不随左右变化而重写定位逻辑
真正难搞的不是画出来,而是当某条内容突然多出三行文字、或用户开了系统级大字体、或切换深色模式时,圆点还稳稳钉在内容中间,主线不断不偏——这得靠伪元素 + 相对定位 + CSS 变量三者咬死,少一个环节都容易露馅。
语义对了,屏幕阅读器能读出“第1项、第2项”,datetime 属性也能被搜索引擎和无障碍工具识别;更重要的是,后续想加“当前进行中”状态,可以用 ol > li:nth-child(3) 精准命中,不用靠 class 切换或 JS 查找。常见错误是写成 ...,这种结构一加 hover 动画或 IntersectionObserver 就得反复改选择器。
::before 画主线时,position: absolute 必须配 position: relative 在父容器上
否则伪元素会相对于 定位,主线偏移、断开、随滚动错位全由此起。实操要点:
-
必须设 position: relative
-
.timeline::before 设 content: ""、position: absolute、left: 50%、transform: translateX(-50%)、width: 2px、height: 100%
- 漏掉
position: relative,或者把 transform 写成 translateY(-50%)(这是垂直居中圆点用的),主线就会歪到左边或消失
每个时间点的圆点必须用 ::after + top: 50%; transform: translateY(-50%)
不是 margin-top 推,也不是 line-height 挤,更不能用 vertical-align(它对块级元素无效)。关键原因:
-
内容高度不固定(比如文字换行),只有 top: 50% + translateY(-50%) 能保证圆点始终钉在整块内容的垂直中心
- 如果用了
margin-top: 20px,字体一变、行数一增,圆点就卡在第一行末尾,视觉上严重错位
-
必须设 position: relative,否则 ::after 的 top 会相对于
计算,导致所有圆点叠在一起
左右交替布局别用 float 或硬写 left/right,用 :nth-child(odd/even) 控制 padding 和 text-align
移动端缩放、字体加载延迟、RTL 语言(如阿拉伯语)都会让 float 失效或翻车。正确做法:
-
.timeline li:nth-child(odd) .timeline-content 设 text-align: right、padding-right: 80px
-
.timeline li:nth-child(even) .timeline-content 设 text-align: left、padding-left: 80px
- 圆点统一用
left: 50% + transform: translateX(-50%),不随左右变化而重写定位逻辑
真正难搞的不是画出来,而是当某条内容突然多出三行文字、或用户开了系统级大字体、或切换深色模式时,圆点还稳稳钉在内容中间,主线不断不偏——这得靠伪元素 + 相对定位 + CSS 变量三者咬死,少一个环节都容易露馅。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











