<colgroup> in HTML: styling entire table columns at once

The colgroup tag applies a width, background or style to an entire table column in one rule, without touching individual cells.
5 min read
Believemy logo

You are building a pricing comparison table on a product page, with a final column that should stand out visually from the rest, a different background, a minimum width. Adding that styling cell by cell, row after row, means repeating the same CSS rule on every <td> in the column, tedious work that breaks the moment a row is added.

The <colgroup> tag solves exactly this problem: it targets an entire table column in one go, applying a width or a background, without touching the content of any cell.


Definition

<colgroup> is a container that groups one or more <col> elements, each representing one column of the table. It displays no content on its own: its only role is to carry presentation attributes that apply to the whole column it describes.

Its position in the document is fixed by the HTML specification: it must appear right after <caption> if there is one, and before the content of the table, meaning before the first row. Placed anywhere else, a browser silently moves it or ignores it, which makes the mistake hard to spot.

Good to know

A misplaced colgroup, for instance after the first rows of the table, triggers no visible console error. The browser simply reinterprets it or ignores it, and the expected column style never shows up. If a colgroup seems to have no effect, always check its position first, right after the opening of the table or its caption.


Syntax: col and span

In its most common form, colgroup holds one col per column to style, in the order the columns appear in the table. An empty col, with no particular style, simply marks that no rule applies to that specific column.

The span attribute, set on colgroup or on a col, avoids repeating identical elements: span="2" on a single col is equivalent to writing two consecutive col elements sharing the exact same style, handy when several neighbouring columns need the same rule.

HTML
<table>
<caption>Plan comparison</caption>
<colgroup>
<col span="2">
<col class="total-column">
</colgroup>
<tr><th scope="col">Essential</th><th scope="col">Plus</th><th scope="col">Yearly total</th></tr>
<tr><td>$10.90</td><td>$21.90</td><td>$262.80</td></tr>
</table>


A concrete example: highlighting a total column

Take this plan comparison table, with a "Yearly total" column that should stand out from the rest. With colgroup, a single rule set on the matching col is enough to give it a different background and a minimum width, without touching the content of any td in that column.

HTML
.total-column {
  background-color: #fdf2e9;
  width: 140px;
}

That rule applies automatically to any row added later to the table: there is no need to touch the CSS every time a plan is added, unlike a class that would need setting on every cell of the column.


Semantics and accessibility

colgroup carries no semantic value for assistive technology: a screen reader never announces it, and its absence changes nothing about how a table is read out. Its role is purely visual. A table's accessibility rests elsewhere, on caption for the title and on <th> for column and row headings.

Only a handful of CSS properties actually apply through colgroup or col: background colour, width, visibility, and border with uneven support across browsers. Text properties such as text colour or weight do not propagate down to the cells, because a column is not a box that visually contains its content, only cells actually are.

ElementStyle reachEffective CSS properties
colgroup, colAn entire columnBackground, width, visibility
trAn entire rowAll usual properties
td, thA single cellAll usual properties


Best practices

Always place colgroup right after caption, or as the very first child of the table if there is no caption. Prefer span over repeating several identical col elements once three columns or more share the exact same style. Keep colgroup for visual styling only: a table's structure and meaning must stay readable even with its style fully stripped away.


Frequently asked questions

Question

Why does my text stay unbold even though I set font-weight on my colgroup?

Because text properties, such as font weight or text colour, are not among the properties CSS actually applies through colgroup or col. Only background, width and visibility genuinely propagate. To make text bold, you need to target the cells directly, for example with an nth-child selector or a class set on each td.

Question

Do I need a col for every column of the table, even ones I do not want to style?

No, only for the columns you intend to target. But if unstyled columns come before a styled one, you must include an empty col for each of them, so the styled col keeps its correct position in the table. The order of col elements must always match the actual order of the columns.

Question

Does colgroup change the order in which a screen reader announces the columns?

No, it has no effect on that at all: colgroup is ignored by assistive technology, which relies only on the structure of rows and cells, together with the headings carried by th and the scope attribute, to understand how the table is organised.

Related terms

Discover our hTML and CSS glossary

Browse the terms and definitions most commonly used in HTML and CSS development.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.