Web Development · Lesson 5
HTML Tables
Build HTML tables with caption, row, header, and data cells, style them with CSS3, span cells, and reserve tables for tabular data.
Lesson purpose
Lesson 5 teaches students to present information that naturally belongs in rows and columns — staff directories, price lists, schedules, grades — as an HTML table styled with CSS3. Students build table structure with five elements, format it with CSS3 properties instead of deprecated HTML attributes, merge cells with colspan and rowspan, and learn the judgment call at the center of the lesson: a table is for tabular data, never for laying out a page. Page layout belongs to the HTML5 structure elements students met earlier.
Quick opener: ask students where they have seen a table this week (class schedule, bank statement, sports standings). Each one compares data across rows and columns — exactly what a table is for.
Learning objectives
By the end of the lesson, students should be able to:
- CIW 2.1.5: Design and format HTML tables to present information in an organized way.
- Build valid table structure with
<table>,<caption>,<tr>,<th>, and<td>. - Style borders, spacing, size, color, and alignment with CSS3 rather than deprecated HTML attributes.
- Span cells across columns and rows with
colspanandrowspan. - Decide when a table belongs on a page and when HTML5 structure elements should be used instead.
- Explain how a responsive (Bootstrap) table keeps wide data usable on small screens.
1. Why tables instead of <pre>
Tables have been part of HTML since HTML 2.0 and have expanded ever since. Students already know the <pre> tag can line up text in columns, but <pre> is extremely limited: it only preserves spacing in monospaced text. A real table allows images, alignment, color, borders, spacing, and many other customizations, and — just as important — it tells browsers and screen readers that the content is a grid of related data.
Check for understanding: “If <pre> can line text up in columns, what does a table add?” (Styling control, semantic meaning, and accessibility.)
2. The five table elements
Every table is built from the same small set of paired tags. None are self-closing.
| Element | Tag | Required? | What it does |
|---|---|---|---|
| Table | <table>...</table> |
Required | Creates the table; contains every other table element. |
| Table caption | <caption>...</caption> |
Optional | Adds a title, which appears above the table by default. |
| Table row | <tr>...</tr> |
Required | Holds all the cells for one row. |
| Table header | <th>...</th> |
Optional | Labels a column or row; bold and centered by default. |
| Table data | <td>...</td> |
Required (unless <th> is used) |
Holds the actual values; left-aligned by default. |
Talking points for each element:
<table>is the container. Every other table tag lives inside it.<caption>is the table’s title. It is optional but strongly recommended because it tells readers — and screen-reader users — what the table is about. It must be the first thing inside<table>.<tr>creates one row. Cells always go inside a row; a cell is never placed directly inside<table>.<th>vs.<td>is more than appearance.<th>tells the browser and assistive technology “this cell is a label”;<td>holds the data being labeled. Typically header cells run across the top row or down the left column.
Figure 5-1 in the book labels the other visible parts of a table that CSS controls: the table border, the cells, the padding inside each cell, and the border spacing between cells.
Quick check: “Which tags could you leave out and still have a working table?” (<caption> and <th>.)
The lesson’s HTML Tables video walks the same build order students will use in Lab 5-1: add the <table> element, add a <caption>, decide the column headings, add a header row of <th> cells, then add a <tr> of <td> cells for each record. It then previews the CSS used to format a table (border, padding, height, width, background color, text alignment, vertical alignment) and closes by contrasting tables with the HTML5 structure elements used for page layout.
The example table
<table>
<caption>Table Elements</caption>
<tr>
<th>Price</th>
<th>Quantity</th>
</tr>
<tr>
<td>13.95</td>
<td>72</td>
</tr>
</table>
table,
td,
th {
border: 1px solid gray;
}
td,
th {
padding: 15px;
}
td {
text-align: center;
}
Walk through it line by line:
<caption>Table Elements</caption>— the title, first inside<table>, rendered above the grid.- First
<tr>— the header row. Two<th>cells, Price and Quantity, label the columns and appear bold and centered. - Second
<tr>— a data row. Two<td>cells hold the values. Each record gets its own<tr>, and each row should have as many cells as there are columns. table, td, th { border: ... }— one grouped selector draws a gray line around the table and around every cell.td, th { padding: 15px; }— adds space inside every cell.td { text-align: center; }— centers the data values;<th>is already centered by default.
Point out the indentation: each nesting level is indented so it is obvious which tags are inside which. The browser does not care, but people reading and debugging the code do.
Common mistake: forgetting a closing </tr>. The next row then ends up inside the previous one and the table renders incorrectly. The validator will catch it.
3. Style tables with CSS3, not HTML attributes
Older HTML used a border attribute on the table tag (<table border="1">): "1" showed a border, "0" or no attribute showed none. By default, tables have no visible border. The border attribute and similar presentational attributes are deprecated in HTML5 and will not pass validation, so all table styling goes in CSS.
Tech note from the book: do not confuse the CSS border property with the old HTML border attribute. The property defines the border’s width, line style, and color.
The same CSS properties can be applied to any table element — table, tr, th, or td. The selector decides where the style lands.
| Property | What it controls | Values |
|---|---|---|
border |
Border width, line style, and color | e.g., 1px solid gray |
border-collapse |
Merges adjacent cell borders into one line | collapse |
border-spacing |
Gap between adjacent cell borders | pixels |
padding |
Space between cell content and its border | pixels |
width |
How far the table or cell extends horizontally | pixels or percent |
background-color |
Fill color behind table elements | color name or hex code |
text-align |
Horizontal alignment | left, center, right, justify |
vertical-align |
Vertical alignment | top, middle, bottom |
Have students predict each change before you show it.
Borders
th, td { border: 1px solid black; }
table { border-collapse: collapse; }
border— the three values are width, style, and color. Applied toth, td, every cell gets its own box, with a small gap between boxes because browsers keep cell borders separate by default. Ifborderis applied only totable, you get one line around the outside and no lines between cells.border-collapse: collapse— merges neighboring borders into a single shared line, producing the clean grid most people expect. It goes on thetable, because it controls how the cells fit together.
Spacing
table { border-spacing: 6px; }
td { padding: 15px; }
These are the pair students mix up most:
border-spacingadds space between cells. It only works when borders are separate; withborder-collapse: collapsethere is no gap to size. It goes on thetable.paddingadds space inside a cell, between the text and the border. It makes tables much easier to read. Useth, tdas the selector to pad header cells too.
Memory aid: text touching the cell border → padding. Cells jammed against each other → border-spacing.
Width and background color
table { width: 90%; }
th { background-color: #CBB677; }
width— by default a table is only as wide as its content. Width can be pixels (fixed) or a percentage (a share of the containing space). Prefer percentages: a 900px table may not fit on a phone, but a 90% table always fits.background-color— accepts a color name (green) or hex code (#00FF00). Here only the header cells change because the selector isth.tdcolors data cells,trcolors whole rows, andtablecolors everything. Keep strong contrast between text and background so the table stays readable.
Alignment
td { text-align: right; }
td { vertical-align: top; }
text-alignis left-to-right position. Right-aligning numbers lines up decimal points like a spreadsheet, which makes prices easier to compare. In a real page, right-align only the number column with a class (for example,td.price).vertical-alignis top-to-bottom position; the default ismiddle. It matters only when a row is taller than its content — for example, when one cell holds a long description and the others hold a single word.
4. Default alignment and consistency
With no CSS applied, browsers render:
| Cell type | Horizontal | Vertical | Weight |
|---|---|---|---|
<th> header cell |
center | middle | bold |
<td> data cell |
left | middle | normal |
Both types are vertically centered by default; the difference is horizontal position and boldness.
Consistency rule: align content consistently within each column. If each row uses a different horizontal alignment, the table looks unplanned. Numbers and prices are commonly right-aligned.
Troubleshooting connection: if a “header” row appears left-aligned and not bold, the cells were probably written as <td> instead of <th>. Fix the markup — no CSS is needed.
Aligning one cell or a whole row
When cell content wraps onto several lines, a neighboring short cell stays vertically centered. The book shows two ways to move “William Gates” to the top of its cell:
/* Option 1: the whole row */
tr {
vertical-align: top;
}
/* Option 2: only cells with the class */
td.valign {
vertical-align: top;
}
<tr>
<td class="valign">William Gates</td>
<td>Known to most as "Bill Gates." ...</td>
</tr>
- A rule on
traffects every cell in the row. - A class such as
valignaffects only the cells that carry it and can be reused on any<td>. - In the book’s example, both produce the same result because the long description cell is already full from top to bottom.
5. Height, width, and centering the table
The book demonstrates sizing with the same two-row Table Examples biography table (Bill Gates and Linus Torvalds), changing one setting at a time:
- Table height (Figure 5-8) — setting
height: 500pxon the CSS table rule makes the table taller and distributes the extra height evenly across all rows. Extra height can waste page space, so use it only when it improves readability. - Cell height (Figure 5-9) — the table height is removed and a 75px height class is applied only to the cell containing Description. The figure caption names the rule
td.height { height: 75px; }, but Description is a header cell, so in students’ own code the selector must match the element that carries the class (th.height, or simply.height). That makes the entire header row 75px tall, because every cell in a row shares a height. If several cells in a row set different heights, the largest value wins; the order of the rules does not matter. - Column width (Figure 5-10) — all heights are removed and
th.width { width: 50%; }is applied to the first<th>(Individual). Setting a header cell’s width sizes its whole column. - Table width and centering (Figure 5-11) — the table’s width is changed to 70% and the table is centered on the page.
- Percent sizing — the book calls percentages the better practice so tables render properly on every device, including small screens.
- Centering the table — create a class with automatic side margins and apply it to the table. The browser splits the leftover space equally on both sides — the same technique used to center an image.
table.center {
margin-left: auto;
margin-right: auto;
}
<table class="center">
Common mistake: using text-align: center to center the table on the page. text-align moves content inside cells; it does not move the table itself.
6. Spanning columns and rows
colspan and rowspan are HTML attributes (not CSS) that let one cell stretch across more than one column or row. Both work on <th> and <td>, and a table can use both. On a <th>, the value is the number of header positions the cell covers; on a <td>, it is the number of standard data cells it covers.
The Column and Row Spanning video reviews both examples below; play it before the code walkthrough.
colspan
<tr>
<th colspan="2">
Brief Biographies of Bill Gates and Linus Torvalds
</th>
</tr>
colspan="2"stretches this header across two columns.- The row previously had two
<th>cells; because one cell now fills both spaces, the other header cell is removed. - Typical use: a title row above several columns.
rowspan
<tr>
<th rowspan="3">
Bill Gates and Linus Torvalds
</th>
<th>
Biographies
</th>
</tr>
rowspan="3"stretches the cell down across three rows: the row it starts in (beside the Biographies header) plus the two biography rows below it.- The rows below have one fewer cell, because the spanning cell already occupies that space.
- Watch the wording: the book’s text says the cell “spans two rows,” meaning the two data rows, while the code counts all three rows the cell occupies. The
rowspanvalue is always the total number of rows, including the starting row. Ask students to count the rows in Figure 5-13 to see why the value is 3.
The most common mistake: adding colspan or rowspan without removing the cell it replaces. The browser shows no error — the table simply grows an extra cell sticking out of the grid. Have students count columns: a title over a three-column table is colspan="3".
7. Tables vs. HTML5 page structure
For years, developers used invisible tables to lay out entire Web pages, largely because browser support for CSS was weak. In HTML5, the W3C recommends against using tables for page structure. Use the HTML5 structure elements instead:
<header>— top of the page, like a word-processing header (logo, site name).<nav>— navigation links to other pages of the site.<section>— a section of a document, such as an introduction, content, or contact information.<article>— site content such as services, articles, blog posts, images, and video.<aside>— content aside from the main article, such as ads, news feeds, or highlighted links.<footer>— bottom of the page (copyright, contact information).
These elements are understood natively by any HTML5 browser on phones, tablets, and laptops, replacing the old “jack of all trades” <div> approach.
Why layout tables cause problems:
- Pages are hard to update and debug.
- Screen readers announce the page as rows and columns of data, which confuses users.
- Layout tables do not adapt well to different screen sizes.
- A search engine may rank a page lower when tables are used for structure.
Book tech tip: use tables tastefully and sparingly — even legitimate data tables cause problems when overused on a page.
Instructor note: as tables become more complex, students will see why GUI HTML editors are popular. Hand-coding them is still essential so students can read, fix, and customize tables those editors generate.
8. Bootstrap responsive tables
Bootstrap is a free, open-source, front-end framework of HTML and CSS design templates. It is mobile-first and one of the most popular projects on GitHub. Bootstrap tables use light padding and horizontal dividers.
A responsive design site works properly and seamlessly on every screen size and resolution. Bootstrap’s responsive table keeps a wide table from breaking a small-screen layout:
<div class="table-responsive">
<table class="table">
...
</table>
</div>
- The
.table-responsiveclass goes on a wrapper<div>, not on the<table>. - When the table is wider than the screen, it scrolls horizontally inside its own box instead of forcing the whole page to scroll sideways.
- The book describes this as most useful below about 768px wide (phones and small tablets).
- Currency note: the book says Bootstrap is in its fourth version; the current release is Bootstrap 5, where
.table-responsivescrolls at any width when needed and variants such as.table-responsive-mdscroll only below a specific breakpoint (mdis 768px). The concept is unchanged. - A responsive table is still a data table — it does not replace HTML5 structure elements. Bootstrap requires linking its CSS file, so treat this section as awareness rather than something students must build today.
Classroom application
Lab 5-1: Creating HTML5 tables to organize content
Goal: convert the plain-text team list on aboutus_the-team.html into a table.
- Set up — copy
aboutus_the-team.htmland theaboutus\folder fromLesson05\Lab_5-1\into theuCorp\directory, at the same level asaboutus.htmlandindex.html. View it in a browser: the team information is not tabular. - Cut the content — find
<h2>Our Creative Team</h2>and cut (Ctrl+X, not Delete) everything from the<p>below it through “Stella@ucorp.com,” including the<br>tags and the closing</p>— but not</article>. Paste it into a new file and save it asold.txt. Building the empty structure first and adding content later is the easiest way to learn tables. - Build the skeleton — add
<table></table>where the text was, leave blank lines between the tags, add a border rule so the table is visible while building, and add the caption The Men and Women who Keep uCorp Running. - Plan the columns — ask students, on paper, how many columns the content needs and what to call them. Answer: three — Name, Job Title, Email Address.
- Header row — one
<tr>containing three<th>cells, each element on its own line.
<!-- Inside the head tag -->
<style>
table, th, td {
border: 1px solid black;
}
</style>
<!-- Inside the body tag -->
<table>
<caption>
The Men and Women who Keep uCorp Running
</caption>
<tr>
<th>Name</th>
<th>Job Title</th>
<th>Email Address</th>
</tr>
</table>
- First data row — a
<tr>with three<td>cells for Jane Doe, CEO & Founder, jane@ucorp.com, copied fromold.txt. - Center the data with a class — not every cell will be centered, so create a class in
aboutus/aboutus.cssand apply it to the cells:
td.center {
text-align: center;
}
<tr>
<td class="center">Jane Doe</td>
<td class="center">CEO & Founder</td>
<td class="center">jane@ucorp.com</td>
</tr>
Note: the book’s printed step shows “Jame Doe” — a typo; the name is Jane Doe. In HTML, write the ampersand as & so the page validates cleanly.
- Intro paragraph — above the table, below the heading, add: Why are our products so popular? Because the men and women of uCorp work tirelessly to produce nothing but the best.
- Check and validate — view the page (caption, three columns, header row, one data row), then validate at the W3C Markup Validation Service while the file is still short and errors are easy to find.
- Remaining rows — add eight more rows (nine people total) from
old.txt, centered. Point out that<tr>adds rows,<td>adds cells, and<th>defines the categories for each column. - Finish the styling in
aboutus.css:
table {
font-family: Arial, Helvetica, Geneva, Swiss, sans-serif;
font-size: 70%;
width: 90%;
}
table.center {
margin-left: auto;
margin-right: auto;
}
td {
padding: 5px;
}
- The font matches the document font, at a slightly smaller size (70% instead of 80%) because tables often look better that way.
width: 90%leaves a margin inside the section.- Add
class="center"to the<table>tag to center it. - 5px of padding adds white space around the data.
- Save both files, view, correct as needed, and validate again.
Lab 5-2: Customizing HTML5 tables with CSS3 formatting
Goal: make the team table easier to read and more visually appealing. Students can continue from Lab 5-1 or copy the Lab 5-2 starter files into uCorp.
- Bold the caption — wrap the caption text in
<strong>...</strong>inside<caption>. - Color the header row — set the first row’s background to light blue
#6699FF. One way:
tr:first-child {
background-color: #6699FF;
}
tr:first-child selects the first row of the table — the header row. (Preview: :first-child is a CSS pseudo-class; a class on the header row works too.)
- Size the first column — set the first
<th>cell’s width to 93 (px), which sizes the whole Name column:
th:first-child {
width: 93px;
}
- Tighten the padding — change the
tdpadding from 5px to 3px. - Experiment — background colors on cells and rows, font colors, or
border-collapse: collapseso only one line surrounds each cell. The book’s sample result uses alternating blue rows. - Space the footer — add
<br>immediately after</table>so the footer does not crowd the table. (A CSSmargin-bottomon the table is the more modern way to add that space.) - If time permits — remove the table border, refresh, observe the difference, then restore it.
The habit for both labs: save, refresh, and validate after every edit. If something breaks, the last change caused it.
In-book exercises and activity
These are short drag-and-drop matching items in the online book. Use them as quick checks right after the related topic:
- Exercise 5-1: Defining table structure (after the five table elements) — students match
<table>,<caption>,<tr>,<th>, and<td>to their descriptions from Table 5-1. - Exercise 5-2: CSS properties for all table elements (after Lab 5-1) — two sets. The first matches
border,border-collapse,border-spacing, andpadding; the second matcheswidth,text-align, andvertical-align. The book wordstext-alignas controlling line justification andvertical-alignas placement between the top and bottom of the cell, so connect those phrases to “horizontal” and “vertical” before students start. - Activity 5-1: Identifying HTML table attributes and properties (after column and row spanning) — students match
rowspan,colspan,padding,border-spacing, andwidth. The attributes are described by how many rows or columns a single cell can occupy, andpaddingandborder-spacingare the pair most often swapped, so revisit the inside-vs.-between distinction first.
Case study: To use tables or not to use tables
An-Mei supervised a team converting the company’s HTML 4.0 site to HTML5. Reviewing the pages, they found tables used to structure all content, not just tabular content. She reserved tables for content that required a structured layout — numbers, dates, spreadsheet-style lists — and had the team replace layout tables with HTML5 structure elements. It took significant time, but afterward pages were quick to update, future changes were easier, and management was pleased that updates happened faster.
Discussion prompts and target answers:
- What content benefits from a tabular structure? What does not? Comparing numerical data and similar ideas side by side (prices, schedules, grades, specifications) benefits. Long descriptions and images usually do not.
- Why did developers use invisible layout tables for so many years, and what are the disadvantages? They were a simple way to structure pages when CSS support in browsers was weak. They make pages much harder to modify and debug, reduce accessibility, and do not respond to different screen formats.
- Is this situation likely in the workplace today? Less likely because CSS3 and HTML5 are universal, but many businesses still run old, outdated sites, so a new developer could inherit one.
Troubleshooting practice
Present each symptom and have students name the clue before revealing the fix:
- Header cells are left-aligned and not bold → they were coded as
<td>; change them to<th>. - One row merges two people’s names into a single wide cell → a
colspanvalue is too large (or misplaced); recount the columns and fix the cell count. - A homepage laid out with a table confuses screen readers → rebuild the layout with
header,nav,section,article,aside, andfooter. - A table forces the whole page to scroll sideways on a phone → wrap it in
<div class="table-responsive">(Bootstrap) and size it in percentages.
Application project
Have students review an HTML tables reference and the W3C documentation for the <table> element, then browse sites that use tables. Discussion: Do those tables present information effectively? What content is best suited to tabular presentation?
Common misconceptions
- “Tables are a good way to lay out a page.” Tables are for data. Page layout uses HTML5 structure elements and CSS.
- “
<th>is just bold text.” It marks a cell as a label, which browsers and screen readers rely on. Use it for headers even if you restyle it. - “
border="1"is fine.” Theborderattribute is deprecated in HTML5 and fails validation; use the CSSborderproperty. - “Tables have borders by default.” They do not; add a CSS border to see the grid.
- “Padding and border-spacing are the same.” Padding is inside a cell; border-spacing is between cells and has no effect once borders are collapsed.
- “
text-align: centercenters the table.” It only centers content inside cells; center the table withmargin-left: autoandmargin-right: auto. - “The last height rule wins.” Among cells in the same row, the largest height wins regardless of order.
- “
colspanjust widens a cell.” It replaces cells; remove the cell it covers or the grid breaks. - “
colspanandrowspanare CSS.” They are HTML attributes on<th>or<td>. - “Pixel widths are safest.” Percentages adapt to screen size; fixed pixel widths can overflow on phones.
Key terms
- rowspan — an attribute used with
<th>or<td>to span a cell vertically across two or more rows. - colspan — an attribute used with
<th>or<td>to span a cell horizontally across two or more columns. - Bootstrap — an open-source, front-end framework of HTML and CSS design templates.
- Responsive design — a site designed to work properly and seamlessly on all screen sizes and resolutions.
- Deprecated — an older feature, such as the HTML
borderattribute, that should no longer be used and will not pass HTML5 validation.
Lesson summary
- Use tables only for information that naturally belongs in rows and columns.
- Build every table from
<table>,<tr>, and<td>, adding<caption>for a title and<th>for labels. Close every tag and keep each row’s cell count consistent. - Header cells default to bold, centered text; data cells default to left-aligned, normal text. Align consistently within columns.
- Style tables with CSS3 —
border,border-collapse,border-spacing,padding,width,height,background-color,text-align, andvertical-align— never with deprecated HTML attributes. - Add background colors to whole tables, rows, or individual cells by choosing the right selector, and remember that border choices dramatically change a table’s appearance.
- Size in percentages where possible, and center a table with automatic left and right margins.
- Merge cells with
colspan(across columns) androwspan(down rows), removing the cells they replace. - Lay out pages with
header,nav,section,article,aside, andfooter; wrap wide data tables in a responsive container for small screens. - Save, refresh, and validate after every change.
Next lesson: Web Forms — tables organize information on a page; forms collect information from visitors.
Course Notes