Element of
Tables
What does <col> do?
The <col> element, typically implemented as a child element of a parent <colgroup>, can be used to target a column in an HTML table.
Display
block
Null element
This element must not contain any content, and does not need a closing tag.

Using <col>

All the <col>-defined columns in a table have to be declared within a single <colgroup> element at the top of the table. They have to be declared in order (left-to-right), and all vertical columns (defined by the number of table cells in any row) have to be accounted for. Several vertical columns can be "grouped together" by using the span attribute (not to be confused with the colspan attribute). So if you have four vertical columns (four cells in each row), and you want to target the last column for styling, you might do this:

.total {  background-color: #eeeeee;  } 
<table> <colgroup>  <col span="3">  <col class="total"> </colgroup> <tr> <th>Item</th>  <th>Qty.</th>  <th>Price</th> <th>Cost</th>  </tr> <tr> <tr> <td>Bananas</td> <td>5</td> <td>0.50</td> <td>2.50</td> </tr> <tr> <td>Apples</td> <td>2</td> <td>0.25</td> <td>0.50</td> </tr> <tr> <td>Oranges</td> <td>3</td> <td>0.75</td> <td>2.25</td> </tr> <tr> <td colspan="3">TOTAL</td> <td>5.25</td> </tr> </table> 
Item Qty. Price Cost
Bananas 5 0.50 2.50
Apples 2 0.25 0.50
Oranges 3 0.75 2.25
TOTAL 5.25

The problem with <col>

The <col> element seems like a very handy element for styling columns in a table — and it does have some benefits. But there is a big problem: the individual table cells aren't actually contained inside the column. The <col> element only serves to provide information about columns: it isn't the column itself. HTML tables are defined by their rows, not by columns. The result of this is that any style applied to a row will override any style applied to column. Further complicating things is that only a handful of CSS properties can be controlled via the <col> element. The properties that can be controlled are:

  • border
  • background
  • width
  • visibility

So you can control the cell color (background-color) in a column, you cannot control the color of the text. And if one of your rows is colored, the row color will override the column color.

The CSS solution

You can create columns of styling within CSS by using the nth-child selector. The idea here is that you can target the third (or fourth, or whatever) cell in each row, which results in styling a column of rows.


td { background-color: black; color: white; } td:nth-child(3) { background-color: red; color: blue; } td:nth-child(5) { background-color: blue; color: yellow;
<table> <tr> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> </tr> <tr> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> </tr> <tr> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> </tr> <tr> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> </tr> </table> 
Cell Cell Cell Cell Cell Cell
Cell Cell Cell Cell Cell Cell
Cell Cell Cell Cell Cell Cell
Cell Cell Cell Cell Cell Cell

You can also use the odd or even keywords to highlight every other column in a table.

td:nth-child(odd) {  background-color: black;  color: white; }  td:nth-child(even) {  background-color: white;  color: black; } 
<table> <tr> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> </tr> <tr> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> </tr> <tr> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> </tr> <tr> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> <td>Cell</td> </tr> </table> 
Cell Cell Cell Cell Cell Cell
Cell Cell Cell Cell Cell Cell
Cell Cell Cell Cell Cell Cell
Cell Cell Cell Cell Cell Cell

Finally, you can also use the last-child selector to re-create the styling in the invoice-list above. This also allows you to avoid styling the header if you want to, and also add additional styling unavailable with the <col> element.

td:last-child {  background-color: #eeeeee;   font-weight: bold; /* Can't do that with <col> */ } 
<table> <tr> <th>Item</th>  <th>Qty.</th>  <th>Price</th> <th>Cost</th>  </tr> <tr> <tr> <td>Bananas</td> <td>5</td> <td>0.50</td> <td>2.50</td> </tr> <tr> <td>Apples</td> <td>2</td> <td>0.25</td> <td>0.50</td> </tr> <tr> <td>Oranges</td> <td>3</td> <td>0.75</td> <td>2.25</td> </tr> <tr> <td colspan="3">TOTAL</td> <td>5.25</td> </tr> </table> 
Item Qty. Price Cost
Bananas 5 0.50 2.50
Apples 2 0.25 0.50
Oranges 3 0.75 2.25
TOTAL 5.25

The problems with this solution

The nth-child solution breaks down if you have a complicated table with a lot of merged cells. But so does the (already not very good) <col> styling. If you are creating a very complicated table with merged cells, you will probably need to add CSS classes or ids to individual cells, or to table rows. You can combine these approaches too, by specifying the nth-child table cell within specific classes of rows.

Don't use <col>?

There are not a lot of compelling reasons to use the <col> element. It is really only useful for presentational (styling) reasons, which are supposed to be left to CSS. Moreover, it isn't even very effective at providing styling control. There may be some semantic reasons for grouping columns together, or for naming columns, but there are better ways of doing that. Moreover, if you want to make your tabular data machine-readable, it is probably better to provide the data in a more machine-friendly format such as JSON. The <col> element still exists and is valid in HTML, but we can't find many really great reasons to bother with it.

Browser Support for col

AllAllAllAllAllAll