webdevpuneet.com

Gantt Chart Table — Free HTML CSS JS Snippet

Gantt Chart Table · Tables · Plain HTML, CSS & JS · Live preview

CategoryTables

Copy & paste

Source Code

<div class="wrap">
  <div class="gantt-head">
    <h2 class="g-title">Q2 2026 Roadmap</h2>
    <div class="legend">
      <span class="leg-item"><span class="leg-dot" style="background:#6366f1"></span>Engineering</span>
      <span class="leg-item"><span class="leg-dot" style="background:#ec4899"></span>Design</span>
      <span class="leg-item"><span class="leg-dot" style="background:#10b981"></span>Marketing</span>
      <span class="leg-item"><span class="leg-dot" style="background:#f59e0b"></span>Product</span>
    </div>
  </div>

  <div class="gantt-scroll">
    <div class="gantt-grid">

      <!-- Header row -->
      <div class="g-label-head">Task</div>
      <div class="g-months">
        <div class="g-month">April</div>
        <div class="g-month">May</div>
        <div class="g-month">June</div>
      </div>

      <!-- Rows -->
      <div class="g-label">Auth redesign</div>
      <div class="g-bars">
        <div class="g-bar" style="left:0%;width:35%;background:#6366f1" data-tip="Apr 1 – May 7">
          <span class="bar-label">Auth redesign</span>
        </div>
      </div>

      <div class="g-label">API v2 launch</div>
      <div class="g-bars">
        <div class="g-bar" style="left:20%;width:45%;background:#6366f1" data-tip="Apr 20 – May 31">
          <span class="bar-label">API v2 launch</span>
        </div>
      </div>

      <div class="g-label">New design system</div>
      <div class="g-bars">
        <div class="g-bar" style="left:0%;width:55%;background:#ec4899" data-tip="Apr 1 – May 21">
          <span class="bar-label">Design system</span>
        </div>
      </div>

      <div class="g-label">Brand refresh</div>
      <div class="g-bars">
        <div class="g-bar" style="left:30%;width:40%;background:#ec4899" data-tip="Apr 30 – May 31">
          <span class="bar-label">Brand refresh</span>
        </div>
      </div>

      <div class="g-label">Q2 campaign</div>
      <div class="g-bars">
        <div class="g-bar" style="left:33%;width:34%;background:#10b981" data-tip="May 1 – Jun 4">
          <span class="bar-label">Q2 campaign</span>
        </div>
      </div>

      <div class="g-label">SEO overhaul</div>
      <div class="g-bars">
        <div class="g-bar" style="left:55%;width:45%;background:#10b981" data-tip="May 21 – Jun 30">
          <span class="bar-label">SEO overhaul</span>
        </div>
      </div>

      <div class="g-label">Pricing strategy</div>
      <div class="g-bars">
        <div class="g-bar" style="left:10%;width:25%;background:#f59e0b" data-tip="Apr 10 – May 2">
          <span class="bar-label">Pricing</span>
        </div>
      </div>

      <div class="g-label">Enterprise tier</div>
      <div class="g-bars">
        <div class="g-bar" style="left:50%;width:50%;background:#f59e0b" data-tip="May 17 – Jun 30">
          <span class="bar-label">Enterprise tier</span>
        </div>
      </div>

    </div>

    <!-- Today line -->
    <div class="today-line" id="today-line" title="Today"></div>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

CSS Grid: 160px label column + 1fr bar area — no table element
Horizontal bars: position:absolute, left% = start%, width% = duration%
Month dividers: repeating-linear-gradient at 33.33% — no extra HTML elements
Today line: JS-computed left% from current date within the quarter range
Colour-coded bars: one colour per team for visual team separation
Repeating background grid on .g-bars for month column visual alignment
Responsive: overflow-x:auto on container — horizontal scroll on narrow screens
Zero chart library — pure CSS and 10 lines of JavaScript

About this UI Snippet

Gantt Chart Table — CSS Grid Layout, Horizontal Bars, Month Dividers & Today Indicator

Screenshot of the Gantt Chart Table snippet rendered live

A Gantt chart table visualises project tasks as horizontal bars across a timeline, making it easy to see task durations, overlaps, and the overall project schedule at a glance. This snippet provides a complete CSS-based Gantt chart without any chart library: a two-column CSS Grid (task labels + bar area), horizontal bars positioned with left and width percentages, three-column month dividers via repeating-linear-gradient grid lines, colour-coded bars per team, and a JavaScript-positioned "Today" indicator line.

The CSS Grid layout

The gantt-grid uses display: grid; grid-template-columns: 160px 1fr. The left column is a fixed 160px for task labels; the right column fills the remaining space for the bar chart area. Each row pair (label + bars) repeats the two-column pattern. The header row uses .g-label-head and .g-months, which itself uses grid-template-columns: repeat(3,1fr) to show three equal-width month columns.

Horizontal bar positioning

Each .g-bar uses position: absolute within a position: relative .g-bars container. The left CSS property positions the bar's start as a percentage of the container width. The width property controls the bar's duration as a percentage. For a 3-month view (90 days): a task starting on April 20 (day 20 of 90) has left: 20/90*100 ≈ 22%. A task lasting 40 days has width: 40/90*100 ≈ 44%. The data-tip attributes hold human-readable date labels for tooltips.

Month column gridlines

The .g-bars background uses repeating-linear-gradient(90deg, transparent, transparent calc(33.33% - 1px), #f1f5f9 calc(33.33% - 1px), #f1f5f9 33.33%). This draws a 1px grey line at every 33.33% (one-third = one month of three) purely in CSS — no extra HTML elements needed for the vertical grid lines.

The today indicator line

A JavaScript snippet computes the current date's position within the Q2 range (April 1 – June 30). If today falls within the range, the percentage through the quarter is computed and the today-line div is positioned accordingly. The line has a red background and a ::before pseudo-element showing "Today" as a label above it.

Colour-coded bars by team

Engineering bars use indigo, Design uses pink, Marketing uses green, Product uses amber. The legend at the top maps each colour to its team. This visual separation lets viewers scan which team is responsible for each task without reading the label.

Step by step

How to Use

  1. 1
    Review the Gantt chart and today lineThe chart shows 8 tasks across a 3-month quarter. The red "Today" line positions itself based on the current date within the April–June range. If today is outside the range, the line does not appear.
  2. 2
    Update task names and bar positionsEdit each .g-label div text for the task name. Update the .g-bar style: left% is the task start as a percentage of the total period; width% is the task duration as a percentage. Add data-tip for a human-readable date range.
  3. 3
    Add or remove task rowsEach task is a pair of divs: .g-label and .g-bars. Duplicate both divs to add a new task row. Delete both to remove one. The grid auto-expands vertically for new rows.
  4. 4
    Change the time rangeUpdate Q2_START and Q2_END in the JS to your project start and end dates. Update the month headers in .g-months. Recalculate bar left and width percentages as (taskStart - rangeStart) / rangeDuration * 100.
  5. 5
    Add a tooltip on bar hoverEach .g-bar has data-tip="Apr 1 – May 7". Add a mouseover listener: document.querySelectorAll(".g-bar").forEach(b => b.title = b.dataset.tip). Or implement a custom tooltip using the CSS Tooltip snippet.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component mapping a tasks array to bar divs, or "Tailwind" for a Tailwind CSS version.

Real-world uses

Common Use Cases

Product roadmap and quarterly planning charts
The Q2 roadmap structure maps directly to product planning use cases — pair it with the product roadmap card for a now/next/later view. Update the task names to your actual roadmap items, colour-code by team or epic, and set bar positions from your planned start and end dates as percentages of the quarter.
Sprint and project timeline dashboards
Show sprint tasks, milestones, and deliverables on a Gantt chart within a dashboard, alongside a kanban board for status. The today line shows current progress. Bars that have not started appear to the right of today; completed bars appear to the left.
Agency project and campaign timeline views
Use for multi-phase agency projects: discovery, design, development, launch. Colour-code by project phase or client. The three-month view covers the typical agency project engagement duration.
Generate Gantt bars programmatically from project data
Fetch project tasks from an API and compute bar positions: left = (task.startDate - rangeStart) / rangeDuration * 100; width = task.durationDays / rangeDays * 100. Render the .g-label and .g-bar divs from the computed values.
Study CSS positioning and percentage layout techniques
The Gantt bars demonstrate how position:absolute with left and width percentages creates a scalable, responsive timeline. The repeating-linear-gradient technique shows how to draw grid lines purely in CSS without any additional DOM elements.
Content calendar and editorial planning views
Map content types (blog posts, videos, emails, social) to rows with colour-coded bars. The bar duration represents the production and publication window. The today line marks current progress through the editorial calendar.
Related: Spreadsheet Keyboard Navigation Table
See the Spreadsheet Keyboard Navigation Table for a related tables pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

First define your range: const rangeStart = new Date("2026-04-01"); const rangeDays = 91 (April-June = 91 days). For each task: const taskStart = new Date(task.startDate); const taskDuration = task.durationDays; const left = (taskStart - rangeStart) / (86400000 * rangeDays) * 100; const width = taskDuration / rangeDays * 100. Apply these as inline styles: bar.style.left = left.toFixed(1) + "%"; bar.style.width = width.toFixed(1) + "%".

Add an SVG overlay on top of the .gantt-scroll with position:absolute; inset:0; pointer-events:none. For each dependency, draw an SVG path from the right edge of the predecessor bar to the left edge of the successor bar. The path can be a simple elbow: M x1 y1 L x2 y1 L x2 y2 L x3 y2 where x1/y1 is the predecessor end and x3/y2 is the successor start. This requires JavaScript to compute bar positions from the DOM.

The .gantt-scroll already has overflow-x: auto. For a 12-month view, change .g-months to grid-template-columns: repeat(12,1fr) and update the month labels. Change the repeating-linear-gradient to 8.33% (1/12). Set a minimum width on .gantt-grid: min-width: 1200px. Bar percentages automatically span the correct portion of the 12-month view.

Click "JSX" to download. Define a tasks array: [{name, team, start, end, color}]. Define rangeStart and rangeEnd dates. Compute left and width for each task with useMemo. Map tasks to pairs of label div + bar div. Compute the today line position in a useEffect that runs once on mount. For dependencies, manage them as a separate array of {from, to} task index pairs.