DEV Community

Cover image for Create a Gantt chart
Phuoc Nguyen
Phuoc Nguyen

Posted on • Originally published at phuoc.ng

Create a Gantt chart

Here's what we'll cover:

  • Learn how to create a grid with cells of varying widths using the grid-template-columns property.
  • Add a gap between items with ease using the grid-row-gap property.
  • Discover how to precisely position a grid item using the grid-column property.

A Gantt chart is a visual tool that helps project managers track the start and end dates of various tasks involved in a project. Initially designed for manufacturing settings by Henry Gantt in the early 1900s, this chart has now become popular across many industries.

Gantt charts are incredibly useful because they provide a quick overview of how different tasks are progressing and whether they are on schedule or behind. By using this chart, project managers can identify potential issues before they become major problems and adjust schedules accordingly. Furthermore, Gantt charts can be used to communicate project timelines and progress with stakeholders like team members or clients, ensuring that everyone is updated.

In this post, we'll guide you through creating a week-based Gantt chart using CSS grid. Check out the preview of the Gantt chart we'll be creating:

Adding the header

We're going to add a header to our weekly Gantt chart, which will help us track the progress of tasks for different people throughout the week. You can use the same approach to create a monthly chart if needed.

The header will have six cells. The first cell will be left empty, and it will align with the assignee of each row. The other five cells will display the weekdays of a week, starting from Monday and ending with Friday.

Here's a simple markup of the header that you can use to get started:

<div class="gantt">
    <!-- Header -->
    <div class="gantt__period">
        <div></div>
        <div>Mon</div>
        <div>Tue</div>
        <div>Wed</div>
        <div>Thu</div>
        <div>Fri</div>
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

The Gantt chart header is set up using CSS grid. We create a grid container with the display: grid property and set the number and size of columns using grid-template-columns. In our case, we use six columns: one for the assignee name and five for each day of the week. To make sure long names or descriptions fit, we set the first column to a fixed width of 5rem.

Instead of writing out each individual column width, we use the repeat(5, 1fr) function. This function repeats the value 1fr five times, creating five columns with equal width. The 1fr unit lets us define flexible column widths that adjust based on available space. This way, our code is more concise and easier to maintain.

Here's what the CSS declarations for the header look like:

.gantt__period {
    display: grid;
    grid-template-columns: 5rem repeat(5, 1fr);
}
Enter fullscreen mode Exit fullscreen mode

Organizing rows

To create each row of the chart, we use two sections: one displays the assignee's name, while the other shows the tasks assigned to them.

<div class="gantt__row">
    <div class="gantt__assign">Assignee</div>
    <div class="gantt__tasks">
        <!-- Diplay tasks ... -->
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

To achieve the desired layout, we'll use the same approach we used for the header. Specifically, we'll use the display: grid property to set up a grid container, and grid-template-columns to define the number and size of columns in the grid. In this case, we'll use two columns: one for the assignee's name and one for displaying tasks. The first column will have a fixed width of 5rem to provide enough space for long names or descriptions, while the second column will take up the remaining available space (1fr).

Here's an example of what the CSS declarations for each row might look like:

.gantt__row {
    display: grid;
    grid-template-columns: 5rem 1fr;
}
Enter fullscreen mode Exit fullscreen mode

Take a look at the chart now with the header and rows included.

Organizing tasks

The second column in each row shows the tasks with the CSS class gantt__task. These tasks have different variations depending on their current state, whether they are yet to be completed, already done, or overdue. You can customize the appearance of the tasks based on their states, such as by using different background colors.

<div class="gantt__tasks">
    <div class="gantt__task gantt__task--done">...</div>
    <div class="gantt__task gantt__task--overdue">...</div>
    <div class="gantt__task gantt__task--todo">...</div>

    <!-- More tasks ... -->
</div>
Enter fullscreen mode Exit fullscreen mode

The .gantt__tasks CSS class is what makes the tasks section of each row look the way it does. It's responsible for creating a grid container using the display: grid property. We've set up the container to have five columns, one for each day of the week, using grid-template-columns. The repeat(5, 1fr) function tells the container to repeat the value 1fr five times, which makes five columns of equal width that grow or shrink depending on the available space.

To make the tasks easier to read, we've added a small gap between each one using grid-row-gap: 0.25rem;.

Here's what the CSS declarations of the .gantt__tasks look like:

.gantt__tasks {
    display: grid;
    grid-row-gap: 0.25rem;
    grid-template-columns: repeat(5, 1fr);
}
Enter fullscreen mode Exit fullscreen mode

Indicating task duration

To specify how long a task should take, we use the grid-column property. This property indicates a grid item's size and position within the grid by specifying the start and end positions of its grid lines.

For instance, if we want to display a task that spans from Tuesday to Friday in the second row, we can set the grid-column property like this: grid-column: 2 / 6;. This means that the task will start at the second grid line of the column track and end at the sixth grid line, which correspond to Tuesday and Friday respectively.

<div
    class="gantt__task gantt__task--todo"
    style="grid-column: 2 / 6"
>
    ...
</div>
Enter fullscreen mode Exit fullscreen mode

Specifying this property for each task allows us to visualize how long each task takes and identify any potential overlaps or gaps in the schedule. You can see a demo of this feature in the playground below.

Making the chart easier to read

In order to make it easier for users to see the duration of each task, we will add vertical lines between the columns of the chart.

To do this, we will start by adding a new element to display the lines.

<div class="gantt">
    <div class="gantt__lines"></div>
</div>
Enter fullscreen mode Exit fullscreen mode

To position the lines within the chart, we use absolute positioning. This allows us to layer the lines behind the chart content and ensure they don't interfere with any other elements on the page.

To create the vertical lines of the chart, we use the .gantt__lines CSS class. It uses position: absolute to position them relative to their nearest positioned ancestor, which in this case is the .gantt container. The left: 0 and top: 0 properties set the starting position of the lines at the top-left corner of their container. The lines spans the full height of its container, thanks to the height: 100% property. And to ensure that the lines spans across all columns of the chart, we use the width: 100% property.

Lastly, we set a negative z-index value to make sure these lines are positioned behind all other elements on the page and don't overlap with any other content.

Here's what the CSS declarations for positioning lines look like:

.gantt {
    position: relative;
    width: 100%;
}

.gantt__lines {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    width: 100%;
    z-index: -1;
}
Enter fullscreen mode Exit fullscreen mode

To add vertical lines to our Gantt chart, we can split the lines element into six columns: one for the assignee's name and five for each day of the week. We can use CSS grid to make this happen.

To get started, let's create six empty div elements.

<div class="gantt__lines">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</div>
Enter fullscreen mode Exit fullscreen mode

To create a six-column layout for our lines element, we need to set grid-template-columns: 5rem repeat(5, 1fr);. The 5rem value sets the width of the first column, which will show the assignee names. The repeat(5, 1fr) function creates five columns with flexible width that grow or shrink based on available space.

We also need to define one row for our grid using grid-template-rows: 1fr;. This ensures that all vertical borders span across the full height of their container.

.gantt__lines {
    display: grid;
    grid-template-columns: 5rem repeat(5, 1fr);
    grid-template-rows: 1fr;
}
Enter fullscreen mode Exit fullscreen mode

Finally, we can add a border-right property to each grid cell by selecting all divs inside the lines element . This will give our project a clean and organized look.

.gantt__lines div {
    border-right: 1px solid rgb(203 213 225 / 0.4);
}
Enter fullscreen mode Exit fullscreen mode

Take a look at the final result of the steps we've been following:

Conclusion

To sum up, using CSS grid to create a Gantt chart is a quick and efficient method for displaying project schedules and timelines.

By assigning our tasks to rows and using the grid-column property to define their duration, we can quickly identify overlaps and gaps in the schedule. Adding vertical lines to the chart improves its readability and gives it a polished appearance. Overall, CSS grid offers a user-friendly approach to building dynamic layouts for Gantt charts.


If you found this series helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!

If you want more helpful content like this, feel free to follow me:

Top comments (0)