How to Create HTML Tables: The Definitive Guide

HTML tables provide a way for authors to arrange data in the form of text, images, links, and more into a presentable two-dimensional grid layout.

Here, you'll learn how to create HTML tables and the different styling options you can take advantage of for customizing and beautifying your tables to fit your overall needs.

The Anatomy of an HTML Table

HTML tables can be displayed to a web page by using, you guessed it, the table tag. Within this tag, you can create a caption, header, body, footer, and numerous rows and columns to arrange your data to your specifications.

The table tag consists of a number of parameters for basic styling purposes. The parameters themselves aren't as exciting as their CSS equivalents, as the parameters have been deprecated for some time. I'll example in a little bit, but here are the parameters for you to dive into:

  • border: The width of the table border, in pixels. Setting a value of 0 removes the table's border entirely.  You can achieve this same effect by using the CSS border property.
  • bgcolor: The background color of the table, either declared as a color string (red, green, blue, etc.), or a 6-digit hexadecimal RGB code prefixed with a number sign (#), also called a hex code for short.  You can achieve this same effect by using the CSS background-color property and the same rules for the values explained above.
  • align: The position of the table in the containing element. Valid values are left where the table is aligned to the left side of the containing element, right where the table is aligned to the right side of the containing element, and center where the table is displayed in the center of the containing element.  The CSS equivalent allows you to set either margin-left or margin-right properties to auto for left or right alignment, or the margin property to 0 auto for centering.
  • cellpadding: The distance, in pixels, from the edge of each table cell to the edge of each table cell's contents. This spacing applies to all four sides of the inside of the table cell.  You can achieve this same effect by setting the CSS border-collapse property to collapse on the table element, and setting the padding property to each of the table data td elements.
  • cellspacing: The distance, in pixels, between each table cell outer border. This spacing applies to all four sides of the table cell.  You can achieve this same effect by setting the CSS border-spacing property to the table element.
  • width: This attribute defines the width of the table.  You can also set the CSS width property to the table element to define the table's overall width.
  • rules: Defines where rules (border lines) will appear in the table. The following values can be used.

Table Rules, aka Border Lines

The rules attribute values are defined as follows:

  • none: No rules will be displayed in the table. This is the default value.
  • groups: Will cause the rules to be displayed between row groups, including the thead, tbody, and tfoot elements.
  • rows: Will cause the rules to be displayed between each table row.
  • cols: Will cause the rules to be displayed between each table column.
  • all: Will cause all rules to be displayed between every row and column, creating a grid effect.
All of these parameters were fantastic for use back in the 90s. Nowadays, each of these attributes is deprecated, meaning they still work but could be removed for use at any point in the future. You should practice using the CSS equivalents going forward as you can style any table element practically any way you want by creating a set of custom CSS rules for your tables.

A Basic table Example

Here's a very basic example of a table to get your feet wet:

<table>
<tr>
<td>Row 1, Col 1</td>
<td>Row 1, Col 2</td>
</tr>
<tr>
<td>Row 2, Col 1</td>
<td>Row 2, Col 2</td>
</tr>
</table>

Which outputs this result:

Row 1, Col 1Row 1, Col 2
Row 2, Col 1Row 2, Col 2

As you can see, a new table is created containing two rows and two columns, each with a unique text in each table cell to identify each cell's position within the table.

We'll go into each of these tags within the table element shortly.

Table Captions

A table caption can be created by adding a caption tag within the table element at the very top. The table's caption spans the entire width of the table and can display custom text to the user, describing the purpose or contents of the table.

The table caption provides a great opportunity to make your content more readable to your user, identifying the contents or data within the table they're viewing.

<table>
<caption>Table Caption</caption>
...
</table>

Table Rows, Columns, and Cells

There are three main tags you can use to organize your data throughout your tables:

  • tr: Table row, defines a new row within your table element. This tag should wrap any existing table headers or cells within your table row.
  • th: Table header, defines a new header column within your table row.
  • td: Table data, defines a new table cell within your table row.

Building on our previous example, we could add an additional row to the top of our table, creating a table header row:

<table>
<tr>
<th>Col 1</th>
<th>Col 2</th>
</tr>
<tr>
<td>Row 1, Col 1</td>
<td>Row 1, Col 2</td>
</tr>
<tr>
<td>Row 2, Col 1</td>
<td>Row 2, Col 2</td>
</tr>
</table>

Which displays the following output:

Col 1Col 2
Row 1, Col 1Row 1, Col 2
Row 2, Col 1Row 2, Col 2

Using colgroup and col Tags for Column Grouping

Let's say you want to define a certain theme to a few of your columns. You can do so by using the colgroup and col tags together:

<table>
<colgroup>
<col span="2" style="background-color: blue;">
<col style="background-color: red;">
</colgroup>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
<th>Header 4</th>
</tr>
<tr>
<td>Body 1</td>
<td>Body 2</td>
<td>Body 3</td>
<td>Body 4</td>
</tr>
</table>

Which displays the following output:

Header 1Header 2Header 3Header 4
Body 1Body 2Body 3Body 4

Here, we've created a set of rules where the first two columns in the table are blue, the third column is red, then the remaining columns use the default styling set for those columns.

Spanning Multiple Columns

There may be some cases where you'd like your table cell in a specific row to span more than one column. You can easily do this with the colspan parameter, either within a th or td tag:

<table>
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
</tr>
<tr>
<td colspan="2">This spans 2 columns</td>
<td>Only in 1 column</td>
</tr>
</table>

Which displays the following output:

Col 1Col 2Col 3
This spans 2 columnsOnly in 1 column

Spanning Multiple Rows

Spanning multiple table rows is not as widely used and is a bit more advanced. If, for some reason, you need a table cell to span multiple rows of data, you can do so with the following example:

<table>
<tr>
<td rowspan="2">Test 1</td>
<td>Test 2</td>
</tr>
<tr>
<td>Test 3</td>
</tr>
<tr>
<td>Test 5</td>
<td>Test 6</td>
</tr>
</table>

Which displays the following output:

Test 1Test 2
Test 3
Test 5Test 6

As you can see, the "Test 1" table cell spans across the first two table rows, then the third row continues on as normal with two table cells side by side.

I've only used this parameter a handful of times and honestly can't recall any specific uses, but I'm sure someone out there will find it useful in some way or another.

Organizing Your Tables Into Sections

Because I'm a code cleanliness freak, I'm going to introduce a few more tags to help keep your tables more organized. The thead, tbody, and tfoot tags define your header, body, and footer of your table.

Browsers can use these elements for independent styling of your table elements to help visually break up the different sections, making your tables more legible.

You can also set your tables up to scroll only the body of the table and keep your header intact.

Here's a quick code snippet of a table with the three tags implemented:

<table>
<thead>
<tr>
<th>Header Col 1</th>
<th>Header Col 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Body Row 1, Col 1</td>
<td>Body Row 1, Col 2</td>
</tr>
<tr>
<td>Body Row 2, Col 1</td>
<td>Body Row 2, Col 2</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer Col 1</td>
<td>Footer Col 2</td>
</tr>
</tfoot>
</table>

Which displays the following output:

Header Col 1Header Col 2
Body Row 1, Col 1Body Row 1, Col 2
Body Row 2, Col 1Body Row 2, Col 2
Footer Col 1Footer Col 2

Visually, without CSS or any other controls, this is no different than if you omitted the three tags altogether. There is no requirement to use the tags but, especially with tables containing large amounts of data, it's best practice to include these tags. You'll have more control over your output and presentation.

What HTML Tables Should Not Be Used For

Tables should never be used for displaying page elements, or splitting up your pages. Back in the day, this was a quick and easy way to create your page headers, content area, sidebars, etc., but this is the 21st century where responsive design is more important than ever.

Designing your site using table layouts should be avoided at all costs as they will more often than not provide a good user experience on smaller devices, and you should stick to only using them for displaying data when necessary.

Conclusion

HTML tables are very powerful and you can do a lot with them. This article touched on many different table layouts and best practices for building them.

You also saw how you can go into a whole other realm tying in custom CSS rules to beautify them and really make them shine.