纯html无法实现可用甘特图,因缺乏时间轴自适应、像素级日期映射、交互行为及响应式对齐能力;frappe-gantt等轻量库可快速解决。

纯 HTML 无法直接创建可交互、带时间轴缩放和拖拽的甘特图组件;必须结合 JavaScript 渲染逻辑,且推荐用成熟库而非手写 DOM 拼接。
为什么不能只靠 <table> 或 <code><div> + CSS 实现可用甘特图
<p>手动用表格或绝对定位 <code><div> 画条形图,看似能“显示”任务区间,但会立刻卡在几个硬伤上:
<ul>
<li>时间轴刻度无法自动适配(比如从“天”切到“周”,<code>colspan 计算爆炸)
width 和 left 需按像素精确算,日期转毫秒再映射到像素极易出浮点误差overflow-x: auto 会破坏条形图与表头对齐(position: sticky 在复杂嵌套下不可靠)
frappe-gantt 是最轻量又够用的开源选择
它只有单个 JS 文件(约 30KB),不依赖 jQuery 或框架,数据格式极简,适合嵌入现有 HTML 页面快速验证排期。关键点:
- 输入数据是纯 JS 数组,每个任务对象必须含
id、name、start、end(ISO 格式字符串,如"2024-06-10"),支持可选progress(0–100 数字)和dependencies(字符串 ID 列表) - 初始化只需两行:
const gantt = new Gantt(".gantt-container", tasks);<br>gantt.refresh(); - 不修改你页面的 CSS,但要求容器有明确宽高(
height: 600px必须设,否则渲染为空) - 移动端仅支持缩放,不支持拖拽——如果需要真手势操作,得切到
dhtmlxGantt或anychart,但体积翻 5 倍起
用 Chart.js + chartjs-chart-timeline 插件强行做?不推荐
Timeline 图表插件本质是把时间当 X 轴、任务名当 Y 轴的条形图变体,表面能画,但实际踩坑密集:
- 时间轴类型(
time)默认按 UTC 解析,中国用户传"2024-06-10"会被当成 UTC 时间,显示成 6 月 9 日晚 24 点(时区偏移未显式声明) - 条形图宽度由
minLength控制像素值,无法按“自然日”等比例伸缩,缩放后条形会断裂或重叠 - 无法原生支持任务依赖箭头、里程碑菱形标记、资源负载色块分层——这些都得自己用
plugins.afterDraw钩子硬绘,代码量反超直接用甘特专用库
自定义渲染前务必确认这三件事
如果业务强定制(比如要和内部审批流深度联动、或需离线 WebAssembly 加速),决定手写,先钉死约束:
- 时间粒度锁定为“天”——放弃小时/分钟级精度,否则 canvas 绘制帧率和日期计算复杂度指数上升
- 所有日期统一用
new Date().toUTCString()存储和传输,前端展示时再用toLocaleDateString("zh-CN")格式化,避免本地时区污染数据流 - 条形图 DOM 结构必须用
<svg></svg>(非<div>),因为 SVG 的 <code><rect x="" y="" width="" height=""></rect>支持小数坐标且抗锯齿,CSS 百分比布局在滚动时容易失步真正难的不是画出一根横条,而是让 200 个任务在缩放、滚动、更新进度时仍保持 60fps —— 这部分优化工作量远超初始渲染逻辑本身。











