横向时间线必须用grid-template-columns显式定义固定列宽,如repeat(5,150px);时间点与纵向内容须共享同一grid-column并用grid-row跨行;禁用transform位移,ie11/safari旧版需降级为flex布局。

横向时间线必须用 grid-template-columns 显式定义列轨道
横向时间线本质是「时间点沿X轴排列」,不能靠 grid-auto-flow: column 让项目自动填列——那样会丢失对齐锚点,后续纵向内容无法精准关联。必须提前画好列轨道,让每个时间点落在确定的列线上。
常见错误是写成 grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)),这会导致列宽随内容浮动,时间点位置飘移,纵向内容根本找不到对应列。
实操建议:
- 用固定列宽或
minmax(150px, 150px)锁死每列宽度,例如grid-template-columns: repeat(5, 150px) - 若时间点数量不确定,改用
grid-template-columns: repeat(5, minmax(150px, 150px)),避免 fr 单位参与计算 - 给每个时间点元素显式设置
grid-column: 1、grid-column: 2等,确保它落在预期列中,不依赖自动放置
纵向内容需用 grid-row 跨行并绑定同一列
纵向内容(如事件详情、描述段落)要“挂”在某个时间点下方,关键不是靠 margin 或 padding 拉开距离,而是让它和时间点共享同一列,并向下跨行占据空间。否则滚动、缩放时容易错位。
典型翻车场景:时间点设在第2列,纵向内容却用 margin-top: 40px 模拟下拉,结果字体大小一变、行高一调,就脱钩了。
实操建议:
- 时间点元素设
grid-column: 2,纵向内容也设grid-column: 2,保证列对齐 - 纵向内容用
grid-row: 2 / -1(从第2行开始,一直延伸到最后一行),或根据实际高度写死范围如grid-row: 2 / 6 - 外层容器加
grid-auto-rows: minmax(60px, auto),防止内容撑高后行高塌陷
联动交互时避免用 transform 移动时间点或内容
想实现「点击时间点,对应内容高亮/展开」,很多人第一反应是给内容加 transform: translateY(-10px) 做上浮动画。但 transform 会让元素脱离文档流,破坏网格定位关系,尤其在 flex + grid 混合布局里极易引发重排错乱。
更糟的是,IE11 和部分旧版 Safari 对 transform + grid 的组合支持极差,动画卡顿或直接失效。
实操建议:
- 用
opacity和max-height控制展开收起,保持网格位置不变 - 高亮状态改用
outline或box-shadow,不改变元素几何尺寸 - 若必须位移,优先用
margin-top(需配合overflow: hidden防止内容溢出)
IE11 及低版本 Safari 下降级方案要放弃 span 列
grid-column: span 2 在 IE11 完全无效,Safari ≤13.1 对 grid-row: span 支持也不稳定。试图用这些属性做「时间点+标题合并显示」会直接导致布局断裂。
这不是写法问题,是引擎硬伤。强行 polyfill 代价远高于降级。
实操建议:
- 检测
@supports (display: grid),不支持时切换为display: flex; flex-direction: column布局 - 时间点与内容用同级
<div> 并列,通过 <code>margin-left: 160px模拟左侧偏移(假设时间点列宽 160px) - 放弃跨列合并,接受「时间点独立一行,内容紧贴其下」的朴素结构
最易被忽略的一点:横向时间线的列数必须与数据长度严格一致。动态渲染时如果列数写死为 repeat(5, 150px),但只传入3个时间点,最后两列会空着,网格线仍在——这会影响纵向内容的 grid-column 定位逻辑。要么服务端预计算列数,要么用 JS 动态生成 grid-template-columns 字符串。











