Section 1: Overview
The table element provides a markup-based structure for tabular data.
- "Tabular data" is the fancy way of referring to content that you might find in a spreadsheet, calendar, quarterly sales report, or train schedule.
- Not just any data thrown into a table is tabular data, though; tabular data is data that belongs in a table so that it may be accurately understood. (Explanation of CSS vs. Table Layouts)
- HTML tables, like spreadsheets, are made up of cells organized into columns and rows.
- Never use tables to control the structure (layout) of a web page.

Section 2: Basic Tables
Tables are defined with the <table> tag.
- A table is divided into rows with the <tr> tag and each row is divided into data cells using the <td> tag.
- The letters td stands for "table data" which is the content of a data cell.
- A data cell can contain just about anything, including text, images, lists, paragraphs, forms, horizontal rules, and even another table (called a nested table).
- The td element must be a child of a tr element.
-
The basic structure of a
simple table looks something like this:
<table>
<tr>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
</tr>
<tr>
<td>row 2, cell 1</td>
<td>row 2, cell 2</td>
</tr>
</table> -
Here is some CSS to provide some basic borders:
table, td
{
border:1px solid black;
border-collapse:collapse; /* needed to avoid two borders - cell and table */ }- The CSS property-value pair "border:1px solid black;" enables borders to be displayed.
- The CSS property-value pair "border-collapse:collapse;" results in borders that look like what you expect.
-
This code above produces a table that looks like this:
row 1, cell 1 row 1, cell 2 row 2, cell 1 row 2, cell 2 -
Note that if you don't specify CSS styling for borders,
the table will be displayed without any borders.
row 1, cell 1 row 1, cell 2 row 2, cell 1 row 2, cell 2 - Sometimes this can be useful, but most of the time you'll want the borders to show. Borders are discussed in Formatting Tables w/CSS3.
Section 3: Table Headers
You can also specify table headers using a <th> tag.
-
An HTML table has two kinds of cells:
- Header cells – contain header information
- Standard cells – contain data
-
th tags are placed within tr tags.
<table>
<tr>
<th>col 1 header</th>
<th>col 2 header</th>
</tr>
<tr>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
</tr>
<tr>
<td>row 2, cell 1</td>
<td>row 2, cell 2</td>
</tr>
</table> - By default, browsers tend to set header text to bold and center it within its th element.
-
This code above produces a table that looks like this:
col 1 header col 2 header row 1, cell 1 row 1, cell 2 row 2, cell 1 row 2, cell 2
Section 4: Spanning Multiple Columns and Rows (reference only)
colspan
The colspan attribute accepts a positive integer and instructs the browser to create a cell that spans as many columns of the table as the attribute's value indicates.
-
<th colspan="4">Spring</th>
- The colspan attribute can be associated with th and td tags.
- Tables 1, 3, 4, and 5 in the table examples page make use of the colspan attribute. Be sure to look at the source code.
rowspan
The rowspan attribute accepts a positive integer and instructs the browser to create a cell that spans as many rows of the table as the attribute's value indicates.
-
<td rowspan="2">Freshwater</td>
- The rowspan attribute can be associated with th and td tags.
- Tables 3 and 4 in the table examples page make use of the rowspan attribute. Be sure to look at the source code.
Section 5: Scope (reference only)
The scope attribute provides information about the context of a table header, particularly for users with disabilities.
-
<th scope="col">Name</th>
- The browser now understands that the "Name" table heading acts as a column header. Assistive software such as screen readers can take advantage of this attribute and better describe the information presented in the table.
- Similarly, you can add a scope attribute with a value of "row" to the any row headers in the table.
- While the scope attribute has no impact on the visual presentation of the table, it adds a healthy dose of semantics and is a boon to assistive technologies.
- Table 2 in the table examples page includes a scope attribute.
Section 6: Grouping Table Elements (Reference Only)
We'll turn our attention to a collection of elements whose job is to increase the semantic value of your data tables.
Using these grouping elements will result in a more accessible data table.
Each of the first three row group elements – thead, tbody, and tfoot – must appear as direct children of their parent table element.
Table Heading Row Group
The thead element, also known as a table heading row group, contains the row or rows that act as column headings for its parent table element.
- As a child of the table element, the thead element should appear after any caption and colgroup elements (more on these later) and before any tbody, tfoot, or tr elements.
- The thead element may only have tr elements as its children.
- The thead element adds semantic value to the data table by explicitly designating the headers that apply to the entire table.
- There can be only one thead element per table.
- The thead element may contain multiple rows, so long as those rows contain headings that act as headings for the entire table.
-
Additional rows containing more headings or cells with supportive
content are also permitted.
- You could, for instance, add a second row containing td elements that provide more information about the columns to which they belong.
- Tables 1, 2, 4, and 5 in the table examples page include a thead element.
Table Row Group
The tbody element, also known as a table row group, represents one or more rows that make up the body of data of its parent table element.
- The tbody element must be included after any caption, colgroup, and thead elements, should they be present.
- The tbody element may only have tr elements as its children and the tbody itself must be a direct child of a table element.
- There can be multiple tbody elements within a single table.
- To break data set into distinct, logical groupings, you could simply wrap those groupings of table rows into their own tbody elements.
- If you add multiple tbody elements to your table, they must be siblings of one another; no nesting tbody elements allowed!
- tbody elements and tr elements can't be siblings; if your table includes one tbody element, any other rows need to be grouped in their own tbody as well, even if there is only one additional row.
- The tbody element, like the thead and tfoot elements, must appear as a direct child of its parent table element.
- Tables 1, 2, 4, and 5 in the table examples page include a tbody element.
Table Footer Row Group
The optional tfoot element, known as a table footer row group, represents a row or rows whose content consists of the column summaries for its parent table element.
- Although previous versions of HTML only allowed the tfoot element to occur before any tbody or tr elements, but not after, the tfoot element is now also alternatively allowed to occur after any tbody or tr elements.
-
The current specification allows the tfoot element to appear in one of the
following two places:
- After any caption, colgroup, and thead elements but before any tbody or tr elements, or
- After any caption, colgroup, thead, tbody, and tr elements.
- The tfoot element itself doesn't add any particular visual styling to the resulting output; it's simply a grouping element that adds semantic value and improves the table's accessibility.
- Only one tfoot element is permitted per table.
- A tfoot element will always be rendered at the bottom of the table to which it belongs.
- Like the thead and tbody elements, the tfoot element may only have tr elements as children.
- Like the thead element, the tfoot does not directly impose any styling on its children.
- Tables 2 and 4 in the table examples page include a tfoot element.
Column Group
The colgroup element represents a logical grouping of one or more columns in a table.
- The colgroup element must be an immediate child of the table element and should be included after the caption element, if present, and before any thead, tbody, tfoot, and tr elements.
-
Defining one or more column groups, when sensible, also provides you with
an opportunity for richer styling of the table element and its child elements.
- You can, for instance, define a column group that contains three or four columns and use CSS to set the width of that column group.
-
The colgroup has a conditional content model, which means that the rules
governing what elements the colgroup can or can’t contain can change
depending on the condition of the element.
-
The colgroup element has an additional optional attribute,
span, which is a positive integer that describes how many
columns the column group contains.
- If the span attribute is defined, then the colgroup element should not have any child elements.
-
<colgroup span="2"></colgroup>
- If the span attribute is not defined, then the colgroup must contain one or more col elements.
-
<colgroup>
<col/>
<col/>
</colgroup>
- The col element, an empty tag with no content, represents one or more columns in a column group.
- The two examples above each define a column group consisting of two columns.
-
The colgroup element has an additional optional attribute,
span, which is a positive integer that describes how many
columns the column group contains.
- Tables 2 and 5 in the table examples page include a colgroup element.
Section 7: Caption
The <caption> tag defines a table caption.
- The caption element, if included, must be the first child of a table element and must have both a start and an end tag.
-
In most browsers, the caption element appears above its table
and center-aligned.
- We'll see later that this can be altered using CSS.
- While the caption element is optional, you should include one for accessibility purposes and as a general best practice.
- Tables 2 and 4 in the table examples page include a caption element.
Positioning Recap
The elements within a table element must appear in this prescribed order:
- <caption> – Zero or one <caption> elements to define a caption for a table. If it is used, a <caption> element must follow immediately after the opening <table> tag.
- <colgroup> – Zero or one column group (<colgroup>) elements to define column groupings for the table. It must appear after any <caption> element, if one is present, and before any of the following table elements.
- <thead> – Zero or one table heading (<thead>) elements to define the heading section for a table.
- <tbody> – Zero or more table body (<tbody>) elements to identify actual content for the table. A table could have multiple <tbody> elements.
- <tfoot> – Zero or one table footer (>tfoot>) to provide information for the bottom of a table. The table footer is a special case when it comes to where in the sequence of table markup it can appear. It can always appear last in the sequence, but it can also appear right after any of these elements that are present (in this order): <caption>, <colgroup>, and <thead>.
Section 8: Empty Cells
Note that you can create an empty cell using a non-breaking space ( ).
- If you do not include this in a cell, it may lose any formatting that you specify using CSS.
- The empty-cells CSS property specifies how a browser should render borders and backgrounds around cells that have no visible content.
Section 9: Repeat Warning
Remember: HTML tables should never be used to define the layout of HTML pages, but only to store table data in a table.
Section 10: Let's Play
Click the "Edit and Click Me >>" to see the results of the html code in the left panel in the panel on the right.
Then, play around with the html code, making changes and seeing the effect of those changes in the right panel.
Section 11: Resources
- Rediscovering HTML tables provides a thorough discussion of tables that you should read.
- HTML <table> Example & Table Tutorial also extensively discusses tables.
- HTML Advanced: Tables
- HTML Tables Tutorials
- HTML Tables Cookbook
- HTML Table Tutorial
- Tizag HTML Tables