Welcome to Vanilla Breeze
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
HTML-first Gantt chart using native table, progress, and time elements with progressive enhancement to an interactive timeline.
A web component that progressively enhances a semantic <table> into an interactive Gantt timeline. Without JavaScript, users see a fully readable data table with native <progress> bars and <time> elements. With JavaScript, the component renders a visual timeline with positioned bars, swim lane groups, milestones, progress fill, and a today marker.
<gantt-chart title="Q2 Roadmap" show-today show-progress> <table> <thead> <tr><th>Task</th><th>Start</th><th>End</th><th>Progress</th></tr> </thead> <tbody> <tr data-task-id="design" data-group="Design" data-status="in-progress"> <td>Design system</td> <td><time datetime="2026-04-01">Apr 1</time></td> <td><time datetime="2026-04-15">Apr 15</time></td> <td><progress value="75" max="100">75%</progress></td> </tr> <tr data-task-id="api" data-group="Engineering" data-depends="design"> <td>API development</td> <td><time datetime="2026-04-10">Apr 10</time></td> <td><time datetime="2026-04-25">Apr 25</time></td> <td><progress value="30" max="100">30%</progress></td> </tr> <tr data-task-id="launch" data-depends="api" data-milestone> <td>Launch</td> <td><time datetime="2026-05-01">May 1</time></td> <td><time datetime="2026-05-01">May 1</time></td> <td><progress value="0" max="100">0%</progress></td> </tr> </tbody> </table></gantt-chart>
| Attribute | Type | Default | Description |
|---|---|---|---|
title | string | — | Chart heading |
src | string (URL) | — | Path to JSON task data |
view | string | "auto" | Timeline granularity: auto, day, week, month, quarter |
show-today | boolean | — | Show vertical today marker |
show-progress | boolean | — | Show progress fill inside bars |
show-dependencies | boolean | — | Draw dependency arrows between tasks |
compact | boolean | — | Reduced row height and spacing |
Each <tr> in the table body can carry these data attributes to configure the corresponding task bar.
| Attribute | Type | Description |
|---|---|---|
data-task-id | string | Unique task identifier |
data-group | string | Swim lane group (tasks with the same group are visually clustered) |
data-depends | string | Comma-separated task IDs this task depends on |
data-status | string | not-started, in-progress, done, or blocked |
data-assignee | string | Assignee name |
data-milestone | boolean | Renders a diamond marker instead of a duration bar |
data-color | string | Custom bar color (CSS color value) |
The component reads task data from the semantic table structure:
<td> text<time datetime="..."> elements<progress value="..." max="...">data-* attributes on the <tr>Each bar is positioned at left: (taskStart - rangeStart) / rangeTotal * 100% with width: (taskEnd - taskStart) / rangeTotal * 100%. The timeline granularity auto-adjusts based on the date range, or can be set explicitly via the view attribute.
Load task data from JSON via the src attribute. The component creates the semantic table internally.
{ "title": "Q2 Roadmap", "tasks": [ { "id": "design", "name": "Design system", "start": "2026-04-01", "end": "2026-04-15", "progress": 75, "group": "Design", "status": "in-progress" }, { "id": "launch", "name": "Launch", "start": "2026-05-01", "end": "2026-05-01", "milestone": true, "depends": ["design"] } ]}
| Event | Detail | When |
|---|---|---|
gantt-chart:ready |
{ taskCount, dateRange } |
After the component finishes rendering |
gantt-chart:task-click |
{ task } |
When a task bar or milestone is clicked |
| Variable | Default | Description |
|---|---|---|
--gc-task-width | 180px | Left panel (task names) width |
--gc-row-height | 36px | Row height for tasks and bars |
--gc-bar-color | var(--color-interactive) | Per-bar color override |
<table> stays in the DOM (visually hidden) so screen readers get full table semantics with <th>, <time>, and <progress>role="img" and a descriptive aria-labeltabindex="0" for keyboard navigationaria-live="polite" region announces task selectionprefers-reduced-motion: reduce<kanban-board> — Track tasks as draggable cards in columns<impact-effort> — Prioritize tasks on impact vs effort<user-story> — Story cards used as kanban items<review-surface> — Annotate the chart with review pins