Introduction
So far in this unit, we've only considered simple tables with each involved cell consuming one column and one row, so to speak.
However, HTML provides developers with a great amount of power and flexibility in fine-tuning the structure of tables and achieving quite complex layouts using them. Part of this power and flexibility comes from two attributes available on all <th>
and <td>
elements — colspan
and rowspan
.
This chapter is dedicated to learning about these two attributes and how can we use them to create complex table layouts, where given header and/or data cells span two or more columns and/or two or more rows.
Spanning multiple columns
To get a table cell to span multiple columns, we use the colspan
attribute.
colspan
attribute is used to specify the number of columns that a table cell should span.By default, a table cell spans exactly one column. Using colspan
, we can get it to span more than one column, for e.g. 2, 3, 4, and so on.
As an example, let's say we want to represent the following table in HTML:
Item | Available sizes | ||
---|---|---|---|
T-Shirt (Blue) | - | M | - |
Hoodie (Grey) | S | - | L |
Hoodi (Black) | S | M | L |
Striped Shirt (Yellow) | - | M | - |
The important thing to note here is the fact that the 'Available sizes' header spans the space of three columns in the table. Likewise, in order to correctly replicate this table, we need to use colspan
on this header.
Here's the code to replicate the table, leveraging the colspan
attribute on the second <th>
element (the one representing 'Available sizes'):
<table border="1">
<thead>
<th>Item</th>
<th colspan="3">Available sizes</th>
</thead>
<tbody>
<tr>
<td>T-Shirt (Blue)</td>
<td>-</td>
<td>M</td>
<td>-</td>
</tr>
<tr>
<td>Hoodie (Grey)</td>
<td>S</td>
<td>-</td>
<td>L</td>
</tr>
<tr>
<td>Hoodi (Black)</td>
<td>S</td>
<td>M</td>
<td>L</td>
</tr>
<tr>
<td>Striped Shirt (Yellow)</td>
<td>-</td>
<td>M</td>
<td>-</td>
</tr>
</tbody>
</table>
Following what we learnt in the previous chapter to semantically section our tables' rows, we put the header cells inside <thead>
while the rest of the data cells denoting actual content of the table inside <tbody>
.
Besides this, the second <th>
element gets a colspan
of "3"
as it needs to span a total of three columns (beneath it).
The output is illustrated below:
Item | Available sizes | ||
---|---|---|---|
T-Shirt (Blue) | - | M | - |
Hoodie (Grey) | S | - | L |
Hoodi (Black) | S | M | L |
Striped Shirt (Yellow) | - | M | - |
Good!
Keep in mind that colspan
doesn't necessarily have to be on a <th>
element; it can well be used on a <td>
Let's consider an example to help demonstrate this.
Shown below is the time table of a supposed programming bootcamp, somewhere on Mars, teaching only on Mondays, Wednesdays and Fridays, from 10am to 2pm:
10:00 - 11:00 | 11:00 - 12:00 | 12:00 - 13:00 | 13:00 - 14:00 | |
---|---|---|---|---|
Monday | HTML | CSS | ||
Wednesday | HTML | JavaScript | CSS | |
Friday | Git | HTML | JavaScript |
The data cells reading 'HTML', 'CSS', and so on, signify what is taught on which day during which timeframe.
For example, HTML is taught on Mondays from 10am to 12pm for two 1 hour sessions. Similarly, on Mondays and Wednesdays, CSS is taught from 12pm to 2pm, again for two consecutive sessions.
Notice how some data cells span multiple columns in order to depict that the underlying topic consumes more than one session — the likes of 'HTML' and 'CSS'.
Let's now replicate this table using HTML and some colspan
magic:
<table border="1">
<tr>
<th></th>
<th>10:00 - 11:00</th>
<th>11:00 - 12:00</th>
<th>12:00 - 13:00</th>
<th>13:00 - 14:00</th>
</tr>
<tr>
<th>Monday</th>
<td colspan="2">HTML</td>
<td colspan="2">CSS</td>
</tr>
<tr>
<th>Wednesday</th>
<td>HTML</td>
<td>JavaScript</td>
<td colspan="2">CSS</td>
</tr>
<tr>
<th>Friday</th>
<td>Git</td>
<td colspan="2">HTML</td>
<td>JavaScript</td>
</tr>
</table>
10:00 - 11:00 | 11:00 - 12:00 | 12:00 - 13:00 | 13:00 - 14:00 | |
---|---|---|---|---|
Monday | HTML | CSS | ||
Wednesday | HTML | JavaScript | CSS | |
Friday | Git | HTML | JavaScript |
All is great except for one thing: the cells spanning multiple columns have their text left-aligned. The original table presented above has this text center-aligned.
So how could we center-align text in a table cell?
Well, there is nothing special for aligning text inside a table cell; we use the common CSS property for doing so in any element that contains text — text-align
.
The text-align
CSS property
The text-align
CSS property is used to specify the alignment of text in a given element. The possible values are:
left
for left-alignmentright
for right-alignmentcenter
for center-alignmentjustify
for justified-alignment (where the words of every line are spaced out in a way such that the length of all lines is the same).
Following shown are examples of each of these on a dummy piece of text:
<p style="text-align: left">This is some long text in the HTML paragraph element because we want to demonstrate the effect of the CSS text-align property which is an extremely useful property to use in all but the most simplest websites.</p>
<p style="text-align: right">This is some long text in the HTML paragraph element because we want to demonstrate the effect of the CSS text-align property which is an extremely useful property to use in all but the most simplest websites.</p>
<p style="text-align: center">This is some long text in the HTML paragraph element because we want to demonstrate the effect of the CSS text-align property which is an extremely useful property to use in all but the most simplest websites.</p>
<p style="text-align: justify">This is some long text in the HTML paragraph element because we want to demonstrate the effect of the CSS text-align property which is an extremely useful property to use in all but the most simplest websites.</p>
This is some long text in the HTML paragraph element because we want to demonstrate the effect of the CSS text-align property which is an extremely useful property to use in all but the most simplest websites.
This is some long text in the HTML paragraph element because we want to demonstrate the effect of the CSS text-align property which is an extremely useful property to use in all but the most simplest websites.
This is some long text in the HTML paragraph element because we want to demonstrate the effect of the CSS text-align property which is an extremely useful property to use in all but the most simplest websites.
This is some long text in the HTML paragraph element because we want to demonstrate the effect of the CSS text-align property which is an extremely useful property to use in all but the most simplest websites.
Perhaps the most common text alignment on the web is left-alignment, followed by center-alignment. Right-alignment is the lesser used one, with justified-alignment being the least used.
In the following snippet, we augment our HTML in order to centralize the text in every multiple-column-spanning <th>
element:
<table border="1">
<tr>
<th></th>
<th>10:00 - 11:00</th>
<th>11:00 - 12:00</th>
<th>12:00 - 13:00</th>
<th>13:00 - 14:00</th>
</tr>
<tr>
<th>Monday</th>
<td colspan="2" style="text-align: center">HTML</td>
<td colspan="2" style="text-align: center">CSS</td>
</tr>
<tr>
<th>Wednesday</th>
<td>HTML</td>
<td>JavaScript</td>
<td colspan="2" style="text-align: center">CSS</td>
</tr>
<tr>
<th>Friday</th>
<td>Git</td>
<td colspan="2" style="text-align: center">HTML</td>
<td>JavaScript</td>
</tr>
</table>
10:00 - 11:00 | 11:00 - 12:00 | 12:00 - 13:00 | 13:00 - 14:00 | |
---|---|---|---|---|
Monday | HTML | CSS | ||
Wednesday | HTML | JavaScript | CSS | |
Friday | Git | HTML | JavaScript |
Voila! And there's our alignment.
<th>
and <td>
element had an attribute called align
to do what the CSS text-align
property is doing above. It has been deprecated and should no longer be used in new HTML code.Spanning multiple rows
Where spanning multiple columns is done with the help of the colspan
attribute, as we just learnt a while ago, the same is done for rows using rowspan
.
rowspan
attribute is used to specify the number of rows that a table cell should span.Every table cell spans exactly one row by default. Using rowspan
we can change this.
Time to turn to an example.
Consider the table below showcasing a bunch of programming languages and some of their popular frameworks:
Programming language | Framework |
---|---|
JavaScript | Express.js |
JavaScript | Angular |
JavaScript | Next.js |
PHP | Laravel |
PHP | Symfony |
Java | Spring |
Since the first three data rows and then the next two ones correspond to the same programming languages, JavaScript and PHP, respectively, we can reduce the underlying data cells in these rows to single cells.
Something as follows:
Programming language | Framework |
---|---|
JavaScript | Express.js |
Angular | |
Next.js | |
PHP | Laravel |
Symfony | |
Java | Spring |
Replicating this table using HTML is quite easy, for we seek the rowspan
attribute on the first data cell in each of the two concerned rows.
Following is the HTML for the table, with the markup of the <tr>
elements presented in one line for the sake of readability:
<table>
<thead>
<tr><th>Programming language</th><th>Framework</th></tr>
</thead>
<tbody>
<tr><td rowspan="3">JavaScript</td><td>Express.js</td></tr>
<tr><td>Angular</td></tr>
<tr><td>Next.js</td></tr>
<tr><td rowspan="2">PHP</td><td>Laravel</td></tr>
<tr><td>Symfony</td></tr>
<tr><td>Java</td><td>Spring</td></tr>
</tbody>
</table>
Observe the second, third, and fifth <tr>
elements here — they all contain one single <td>
element. The reason of doing so is because by virtue of the colspan
Programming language | Framework |
---|---|
JavaScript | Express.js |
Angular | |
Next.js | |
PHP | Laravel |
Symfony | |
Java | Spring |
As this snippet illustrates, if the markup of an HTML table is more readable when specifying the content of the <tr>
elements in one single line, then we are better off at doing so.