CSS Tables
In this page:
border-collapse
By default, adjacent table cells each draw their own border, creating a doubled-up line between them. border-collapse: collapse merges those into a single clean line. The empty-cells property only matters when border-collapse is set to separate (its effect is suppressed under collapse) -- setting empty-cells: hide removes the border and background from any table cell that has no content, which is useful for sparse data grids. caption-side lets you move a table's <caption> element to the bottom of the table instead of its default position above it.
Note: border-collapse: collapse is almost always what you want for a clean, modern-looking table.
Warning: Some spacing-related properties, like border-spacing, have no effect once border-collapse is set to collapse.
Example: border-collapse
<style>
table {
border-collapse: collapse;
}
td {
border: 1px solid black;
}
</style>
<table>
<tr><td>A</td><td>B</td></tr>
</table>
Table Width
Setting a table's width, most often to 100%, makes it stretch to fill its container instead of shrinking tightly around its own content. table-layout: fixed switches the column-sizing algorithm so the browser uses only the first row's widths (or explicit column widths) to lay out the whole table immediately, instead of the slower default auto algorithm that waits to measure every cell's content first.
Note: width: 100% on a table is a simple, reliable way to make sure it uses the full space available inside its parent container.
Warning: A table with many columns and a fixed width can still force individual cells to feel cramped, sometimes a responsive strategy is needed too.
Example: Table Width
<style>
table {
width: 100%;
table-layout: fixed;
border: 1px solid #ccc;
}
td {
border: 1px solid #ccc;
padding: 8px;
}
</style>
<table>
<tr><td>Stretches to fill its container</td></tr>
</table>
Padding in th and td
Table cells (th and td) need their own padding just like any other element, giving their content breathing room away from the cell's own border.
Note: A padding value between 8px and 12px is a comfortable, common starting point for table cell content.
Warning: Without any padding, table text sits cramped right against the cell border, which hurts both readability and visual polish.
Example: Padding in th and td
<style>
table {
border-collapse: collapse;
}
th, td {
padding: 10px;
border: 1px solid #ccc;
}
</style>
<table>
<tr><th>Header</th></tr>
<tr><td>Cell</td></tr>
</table>
Zebra Striping and Hover Effects
Zebra striping alternates the background color of table rows using the :nth-child(even) or :nth-child(odd) selector, making wide tables much easier to visually scan. A hover effect on tr:hover highlights whichever row a visitor is currently reading.
Note: Keep zebra stripe colors subtle, a very light tint is usually enough to guide the eye without feeling busy.
Warning: A hover effect that changes text color as well as background can sometimes hurt contrast, double check readability on hover too.
Example: Zebra Striping and Hover Effects
<style>
tr:nth-child(even) {
background: #f0f0f0;
}
tr:hover {
background: #ddd;
}
</style>
<table>
<tr><td>Row 1</td></tr>
<tr><td>Row 2</td></tr>
</table>
Responsive Tables
Wide tables can be awkward on small screens. A common fix is wrapping the table in a container with overflow-x: auto, letting visitors scroll the table horizontally without breaking the rest of the page's layout.
Note: Wrapping just the table (not the whole page) in a scrollable container keeps everything else on the page laid out normally.
Warning: Without any responsive strategy, a wide table can force the entire page to scroll horizontally, which is a poor experience on mobile.
Example: Responsive Tables
<style>
.table-wrapper {
overflow-x: auto;
}
table {
border-collapse: collapse;
}
td {
border: 1px solid #ccc;
padding: 8px;
white-space: nowrap;
}
</style>
<div class="table-wrapper">
<table>
<tr><td>Column 1</td><td>Column 2</td><td>Column 3</td><td>Column 4</td><td>Column 5</td><td>Column 6</td><td>Column 7</td><td>Column 8</td></tr>
<tr><td>Value 1</td><td>Value 2</td><td>Value 3</td><td>Value 4</td><td>Value 5</td><td>Value 6</td><td>Value 7</td><td>Value 8</td></tr>
</table>
</div>
- Forgetting border-collapse, which leaves distracting doubled borders between adjacent table cells.
- Skipping padding on th and td, leaving cell content cramped right against its own borders.
- Building a wide, multi-column table with no responsive plan, forcing awkward horizontal scrolling on phones.
- border-collapse: collapse merges adjacent cell borders into clean single lines instead of doubled ones.
- Padding on th and td cells is essential for making table content comfortable to read.
- Zebra striping and row hover effects both make wider tables significantly easier to scan.
All standard CSS table properties covered here are supported by every modern browser.
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: