progress 标签无法实现阶梯式进度图,因其仅支持单值线性填充,缺乏多段独立区间、起点偏移、分段着色及语义化标注能力;须用绝对定位 div 配合 CSS 自定义属性与归一化日期计算实现,并补充可访问性结构。

progress 标签做不了阶梯式进度图——它只支持线性、单值填充,无法表达“多段独立区间+非连续状态+位置精准映射”的需求。
为什么不能用 progress 实现阶梯式进度图
阶梯式进度图(比如项目阶段甘特图、等级里程碑、时间轴式任务节点)本质是多个不重叠、有起止点、可独立着色的区段,而 progress 的语义和 DOM 结构只描述一个从 0 到 max 的连续比例值:
- 它没有“起点偏移”概念,
value只能控制填充长度,不能指定起始位置 - 无法渲染多个颜色不同的段落;伪元素
::-webkit-progress-value和::progress-bar也不支持分段控制 - 所有浏览器都把它当作单一语义组件,无障碍属性(如
aria-valuetext)只能描述整体进度,无法为每个阶梯单独标注
用 div + position: absolute 实现阶梯段落定位
核心思路是把容器设为相对定位,每个阶梯段作为绝对定位子元素,通过 left 和 width 精确控制其在时间轴/数值轴上的位置。适用于已知总跨度(如 0–100%、2024–2030 年、或具体日期范围)的场景:
- 先确定整个时间轴/数值轴的基准宽度(例如
width: 100%或固定像素值) - 对每个阶梯项,计算其
left= 起点占比 × 容器宽度,width= (终点占比 − 起点占比)× 容器宽度 - 用
transform: translateX()替代直接改left更利于动画性能,尤其配合will-change: transform - 若需响应式,避免写死像素值;推荐用 CSS 自定义属性传入比例,再在 calc() 中运算
示例关键片段:
立即学习“前端免费学习笔记(深入)”;
<div class="timeline"> <div class="stage" style="--start: 0.2; --end: 0.45;"></div> <div class="stage" style="--start: 0.5; --end: 0.78;"></div> </div>
CSS 中:
.timeline { position: relative; width: 100%; height: 24px; }
.stage {
position: absolute;
top: 0; bottom: 0;
left: calc(var(--start) * 100%);
width: calc((var(--end) - var(--start)) * 100%);
background: linear-gradient(90deg, #4a6fa5, #6b8cbc);
border-radius: 4px;
}处理日期型阶梯图时怎么算 --start 和 --end
当阶梯依据真实日期(如 2025-03-05 至 2025-08-22)定位,必须统一换算成归一化比例,否则跨年/闰月会错位:
- 取全局最小日期为
minDate,最大日期为maxDate(建议用new Date().getTime()得到毫秒数) - 每个阶段的
startMs = new Date(item.startDate).getTime(),同理得endMs -
--start=(startMs - minMs) / (maxMs - minMs),确保结果在 [0, 1] 区间内 - 注意:JavaScript 的
Date构造函数对格式敏感,"2025-03-05"安全,但"03/05/2025"在 Safari 可能解析失败,务必标准化
容易被忽略的可访问性与键盘焦点问题
纯 div 阶梯图默认不可聚焦、无语义,屏幕阅读器完全无法感知。补救措施不是加 role="progressbar"(它仍要求单值语义),而是按实际信息结构处理:
- 每个阶梯段用
<section role="region" aria-labelledby="stage-1-label">包裹,并配<h3 id="stage-1-label">研发阶段</h3> - 显式写出起止时间文本(即使视觉上隐藏),例如
<span class="sr-only">开始于 2025-03-05,结束于 2025-08-22</span> - 若需键盘导航,给每个
.stage加tabindex="0",并监听Enter触发详情展开 - 不要试图让
aria-valuenow描述“阶梯”,它只适用于线性度量;此处应放弃进度条语义,转而用aria-description补充上下文
真正难的不是把几个色块排成一行,而是让它们既在视觉上准确落在时间轴上,又在 DOM 层和辅助技术层保持各自可理解、可操作、可验证的状态。



















