垂直时间轴必须用<ol>包裹,因其天然序号支持和流式行为是Grid稳定分栏前提;小屏堆叠错位、无障碍混乱等问题均源于语义错误。

垂直时间轴必须用 <ol> 而不是 <div> 包裹
语义错误是后续所有响应式问题的根源。用 <div class="timeline"> 或 <ul> 会导致小屏堆叠错位、无障碍读取混乱、伪元素定位漂移。浏览器对 <ol> 的天然序号支持和流式行为,是 Grid 布局能稳定分栏的前提。
正确结构示例:
<ol class="timeline-grid"> <li><time>2024</time><div class="timeline-content">事件一</div></li> <li><time>2025</time><div class="timeline-content">事件二</div></li> </ol>
-
<ol>不要加list-style: none以外的重置——保留语义比隐藏数字更重要 - 每个
<li>必须设position: relative,否则::before圆点无法锚定在时间点上 - 避免在
<li>内再套<div>容器来“撑高”,这会干扰 Grid 行高计算
grid-template-columns 切换必须配合 grid-auto-rows
只改列数不设行高,时间项高度差异大会导致左右错位、竖线断裂、圆点偏移。Grid 不会自动拉齐两列内容高度,minmax(120px, auto) 是底线。
关键 CSS 片段:
立即学习“前端免费学习笔记(深入)”;
.timeline-grid {
display: grid;
grid-template-columns: 1fr;
grid-auto-rows: minmax(120px, auto);
}
@media (min-width: 768px) {
.timeline-grid {
grid-template-columns: 1fr 1fr;
}
}- 小屏下
grid-template-columns: 1fr比100%更可靠,避免百分比在 flex 容器里失效 - 大屏必须用
grid-auto-rows,不能依赖height或min-height单个项——否则第二列顶部会悬空 - 如果某项内容超长(如含图片或长段落),
auto部分会撑开整行,这是预期行为;强行限制高度会截断内容
左右分栏靠 grid-column,别碰 order
order 在 Grid 中只影响视觉顺序,但会破坏屏幕阅读器读取逻辑和 SEO 时间序列,且在响应式断点切换时极易错乱。真正可控的方式是显式分配列位置。
- 第 1、3、5… 项加
grid-column: 1 - 第 2、4、6… 项加
grid-column: 2 - HTML 保持原始时间顺序不变,CSS 只负责“投射”到哪一列
- 不要用
:nth-child(odd)直接写样式——一旦你加了标题项或分隔符,所有奇偶判断就全崩了
更稳妥的做法:给每个 <li> 加 data-position="left" 或 data-position="right",用属性选择器控制,后期维护可读性更强。
竖线必须由 <ol> 的 ::after 承担,且高度不能写死
常见错误是给每个 <li> 都画一条竖线,结果小屏下线条重叠、大屏下断开、打印时多出一堆虚线。主轴线必须是一条贯穿容器的伪元素。
正确写法:
.timeline-grid::after {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 2px;
background: #ddd;
z-index: 1;
}-
top: 0; bottom: 0是关键——它依赖父容器有明确高度来源,所以前面强调grid-auto-rows和<ol>结构 - 用
transform: translateX(-50%)居中,而不是left: calc(50% - 1px),后者在缩放或高清屏下易偏移 - 移动端若需隐藏竖线(比如改成点状连接),直接
display: none,不要删掉伪元素——否则会触发重排
圆点统一用 <li>::before,位置固定在 left: 50%; top: 50%; transform: translate(-50%, -50%),这样无论时间项高度怎么变,圆点始终居中锚定。


















