Easy Tutorial For Creating HTML Tables That Add Value To Pages
HTML tables are particularly good at creating a logical, and heirarchical structure for complex data sets. A lot of the simple tables you see on the web, such as ecommerce pricing and feature tables, aren’t actually tables. Instead, simple tables are usually created with unordered lists containing column data and CSS to position the lists next to each other. If you want to create these sorts of tables, take a look at our list and CSS tutorials.
On the other hand, if you have a complex data set that needs strong logical structure, HTML tables are the right tool for the job.
Contents
Table Building Blocks
Tables are created by nesting a variety of elements between table
tags. Tables are organized into rows, not columns, by the table row (tr
) element. Each table row is made up of one or more table data (td
)entries. Columns are formed automatically when table data elements from each subsequent table row automatically line up in vertical columns.
Those three elements, table
, tr
, and td
, are the basic building blocks of HTML tables. Here’s an example of how we can use just those three elements to create a simple table:
<table>
<tr>
<td>Mood</td>
<td>Color</td>
<td>Weather</td>
</tr>
<tr>
<td>Happy</td>
<td>Yellow</td>
<td>Sunny</td>
</tr>
<tr>
<td>Sleepy</td>
<td>Gray</td>
<td>Cloudy</td>
</tr>
</table>
And here’s how our simple table will show up in the browser:
Mood | Color | Weather |
Happy | Yellow | Sunny |
Sleepy | Gray | Cloudy |
Adding Structure to a Table
There are additional elements we can use to add semantic meaning to the data in our table. The most important element, and one that should be present for every table, is the table heading th
tag. This tag is used in place of the td
tags in the first row to identify entries that should be used as column headings.
There are other elements which may optionally be used to group table heading, body, and footer elements together. These elements are not required for HTML tables, but if you are working with a very large data set, it’s a good idea to include them.
thead
is the table header container, and it is used to contain the entries with theth
tag.tfoot
is the table footer container. If your data set contains a final summary or disclaimer row, wrap it intfoot
tags and place it immediately after thethead
container. Even though thetfoot
element appears above thetbody
element, when rendered in the browser it will automatically appear at the bottom of the table.- The
tbody
element is used to contain all of the data that should appear between the header and the footer.
In order to implement these structure-adding elements, we need some data to work with.
This image comes from W3Techs, and was captured Feb 2, 2016.
Let’s convert the data in this image into a table making use of all the elements we’ve covered so far.
<table>
<thead>
<tr>
<th>CMS</th>
<th>Usage</th>
<th>Change Since Jan 1</th>
<th>Market Share</th>
<th>Change Since Jan 1</th>
</tr>
</thead>
<tfoot>
<tr>
<td>Totals</td>
<td>33.3%</td>
<td></td>
<td>76%</td>
<td></td>
</tr>
</tfoot>
<tbody>
<tr>
<td>WordPress</td>
<td>25.8%</td>
<td>+0.2%</td>
<td>59.1%</td>
<td>+0.3%</td>
</tr>
<tr>
<td>Joomla</td>
<td>2.8%</td>
<td>No Change</td>
<td>6.4%</td>
<td>No Change</td>
</tr>
<tr>
<td>Drupal</td>
<td>2.2%</td>
<td>+0.1%</td>
<td>4.9%</td>
<td>No Change</td>
</tr>
<tr>
<td>Magento</td>
<td>1.3%</td>
<td>+0.1%</td>
<td>2.9%</td>
<td>No Change</td>
</tr>
<tr>
<td>Blogger</td>
<td>1.2%</td>
<td>No Change</td>
<td>2.7%</td>
<td>No Change</td>
</tr>
</tbody>
</table>
Note that we need to create empty td
elements for every box that should appear empty. Let’s see how our table looks so far:
CMS | Usage | Change Since Jan 1 | Market Share | Change Since Jan 1 |
---|---|---|---|---|
Totals | 33.3% | 76% | ||
WordPress | 25.8% | +0.2% | 59.1% | +0.3% |
Joomla | 2.8% | No Change | 6.4% | No Change |
Drupal | 2.2% | +0.1% | 4.9% | No Change |
Magento | 1.3% | +0.1% | 2.9% | No Change |
Blogger | 1.2% | No Change | 2.7% | No Change |
Adding a Caption
We want our website visitors to understand the data in our table. One thing our table lacks is a caption that describes the contents of the table. We could use a heading element, such as an h2
, and that might be the easiest solution. However, visitors using assistive technologies will gain the most benefit if we use the caption
element and add it to the table itself.
We can add a caption by wrapping it in caption
tags and placing it at the very top of our table
element.
<table>
<caption>Most Popular Content Management Systems</caption>
<thead>
<!--Followed by the rest of the table data-->
Since our data comes from an external source, we really do need to add some sort of attribution to our table. Let’s do that by adding a comment in a row at the bottom of the table explaining the context surrounding our data and giving proper attribution. We should also explain what the Usage and Market Share columns mean to keep our website visitors from having to guess at the meaning of that data.
We want our footer explanation and attribution rows to span the full width of the table – a total width of five columns. To do this we need to use the colspan
attribute.
<!--Preceded by Table Heading Content-->
</thead>
<tfoot>
<tr>
<td>Totals</td>
<td>33.3%</td>
<td></td>
<td>76%</td>
<td></td>
</tr>
<tr>
<td colspan="5">* <strong>Usage</strong> is percentage of surveyed websites
that use the associated CMS. <strong>Market Share</strong> is the percentage
of surveyed websites powered by a CMS that use the associated CMS. For example,
25.8% of all surveyed websites use WordPress, and WordPress commands 59.1%
market share of the total CMS market.</td>
</tr>
<tr>
<td colspan="5">The data in this table is provided courtesy of
<a href="http://w3techs.com" target="_blank">W3Techs</a> and was captured in
February 2016. To learn more about this topic visit the
<a href="http://w3techs.com/technologies/overview/content_management/all"
target="_blank">overview of content management systems</a> from W3Techs.</td>
</tr>
</tfoot>
<tbody>
<!--Followed by Table Body Content-->
Combining Duplicated Content
We can clean up our table a little by collapsing duplicated content. For example, in the far left-hand column we have the value “No Change” expressed four times in a row. We could collapse all four values into a single cell using the rowspan
attribute.
To use rowspan
we need to identify the first td
element that we want to include in the block of grouped cells. Here it is:
<!--Preceded by WordPress Row-->
<tr>
<td>Joomla</td>
<td>2.8%</td>
<td>No Change</td>
<td>6.4%</td>
<td rowspan="4">No Change</td>
</tr>
<!--Followed by Drupal Row-->
We do need to take one other step when we add this modification to our table HTML and that is to delete the final td
element from each of the data sets that we want to collapse into our rowspan
. If we don’t don’t delete the td
elements that are to be collapsed into the rowspan
they will remain in the flow of the table, but appear next to the rowspan
floating on the right-hand side of the table.
Pulling it All Together
Let’s pull together our table code, the caption, the footer comment, and the column-collapsing code into one cohesive code block.
<table>
<caption>Most Popular Content Management Systems</caption>
<thead>
<tr>
<th>CMS</th>
<th>Usage *</th>
<th>Change Since Jan 1</th>
<th>Market Share *</th>
<th>Change Since Jan 1</th>
</tr>
</thead>
<tfoot>
<tr>
<td>Totals</td>
<td>33.3%</td>
<td></td>
<td>76%</td>
<td></td>
</tr>
<tr>
<td colspan="5">* <strong>Usage</strong> is percentage of surveyed websites
that use the associated CMS. <strong>Market Share</strong> is the percentage
of surveyed websites powered by a CMS that use the associated CMS. For example,
25.8% of all surveyed websites use WordPress, and WordPress commands 59.1%
market share of the total CMS market.</td>
</tr>
<tr>
<td colspan="5">The data in this table is provided courtesy of
<a href="http://w3techs.com" target="_blank">W3Techs</a> and was captured in
February 2016. To learn more about this topic visit the
<a href="http://w3techs.com/technologies/overview/content_management/all"
target="_blank">overview of content management systems</a> from W3Techs.</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>WordPress</td>
<td>25.8%</td>
<td>+0.2%</td>
<td>59.1%</td>
<td>+0.3%</td>
</tr>
<tr>
<td>Joomla</td>
<td>2.8%</td>
<td>No Change</td>
<td>6.4%</td>
<td rowspan="4">No Change</td>
</tr>
<tr>
<td>Drupal</td>
<td>2.2%</td>
<td>+0.1%</td>
<td>4.9%</td>
<!--Deleted td element to be collapsed with rowspan-->
</tr>
<tr>
<td>Magento</td>
<td>1.3%</td>
<td>+0.1%</td>
<td>2.9%</td>
<!--Deleted td element to be collapsed with rowspan-->
</tr>
<tr>
<td>Blogger</td>
<td>1.2%</td>
<td>No Change</td>
<td>2.7%</td>
<!--Deleted td element to be collapsed with rowspan-->
</tr>
</tbody>
</table>
With all of our changes pulled together, here’s how our table looks.
CMS | Usage * | Change Since Jan 1 | Market Share * | Change Since Jan 1 |
---|---|---|---|---|
Totals | 33.3% | 76% | ||
* Usage is percentage of surveyed websites that use the associated CMS. Market Share is the percentage of surveyed websites powered by a CMS that use the associated CMS. For example, 25.8% of all surveyed websites use WordPress, and WordPress commands 59.1% market share of the total CMS market. | ||||
The data in this table is provided courtesy of W3Techs and was captured in February 2016. To learn more about this topic visit the overview of content management systems from W3Techs. | ||||
WordPress | 25.8% | +0.2% | 59.1% | +0.3% |
Joomla | 2.8% | No Change | 6.4% | No Change |
Drupal | 2.2% | +0.1% | 4.9% | |
Magento | 1.3% | +0.1% | 2.9% | |
Blogger | 1.2% | No Change | 2.7% |
Conclusion & Next Steps
Tables give us a way to present data sets in a way that is easy to digest. Table syntax in HTML is fairly straightforward and with just a little practice you’ll be creating complex tables with ease.
Our table looks pretty good right now, and includes all of the critical elements. However, there’s a lot more we can do with this table.
- The table caption could use some styling to add emphasis and draw attention.
- The explanation and attribution comments in the table footer need to shrink in size a bit so that they aren’t quite as prevalent.
- The first column entries could be styled differently from the rest of the table data cells.
- The empty cells in the “Totals” row could use some styling to make it clear that they are supposed to be empty.
- We may want to center the contents in our
td
elements. - This table doesn’t look very good on a small screen. We should make some changes so that it renders a little better on smaller devices.
We’ll implement all of these changes in our next tutorial: Styling Tables.