← Back to CSS Course | Chapter 4: Text & Fonts | Lesson 10 of 10

CSS Tables

Tables are the right tool whenever data genuinely belongs in rows and columns, like a pricing comparison or a spec sheet. On their own, browsers render tables in a rather plain, cramped way, but a small amount of CSS turns them into something much more readable. border-collapse merges double borders between cells into clean single lines, th and td padding gives cells breathing room, zebra striping (alternating row colors) makes wide tables easier to scan, and a hover effect can highlight whichever row a visitor is currently reading. On smaller screens, tables often need extra care to stay usable without forcing awkward horizontal scrolling. A well-styled table on a site like cookiescursor.com turns raw data into something visitors can actually scan and compare at a glance.

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

css
<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

css
<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

css
<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

css
<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

css
<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>
Common Mistakes
  1. Forgetting border-collapse, which leaves distracting doubled borders between adjacent table cells.
  2. Skipping padding on th and td, leaving cell content cramped right against its own borders.
  3. Building a wide, multi-column table with no responsive plan, forcing awkward horizontal scrolling on phones.
Chapter Summary
  • 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.
Browser Support

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:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.