CSS Table Styling

CSS Table Styling

Tables communicate relationships between rows and columns; CSS should improve that structure without discarding the semantics.

What you’ll learn

  • Style semantic table headings and cells.
  • Compare borders, spacing and zebra stripes.
  • Make large tables scroll safely on narrow screens.

Understand the concept

A table uses <caption>, <thead>, <tbody>, and proper <th scope="col"> headers. Use border-collapse for clean lines, padding for readable cells, and tbody tr:nth-child(even) for alternating rows.

Wrap a wide table in a container with overflow-x:auto rather than forcing tiny text or changing data-table semantics.

What the browser evaluates

Padding affects cell readability; collapsed borders avoid double edges; nth-child colors rows by position; an overflow container preserves table columns.

Borders and readable cells

Start with semantic headings and cell spacing.

HTML

<div class="table-wrap"><table><caption>Fruit prices</caption><thead><tr><th scope="col">Fruit</th><th scope="col">Price</th></tr></thead><tbody><tr><td>Apple</td><td>$3.00</td></tr><tr><td>Banana</td><td>$1.50</td></tr><tr><td>Orange</td><td>$2.00</td></tr></tbody></table></div>

CSS

.table-wrap { overflow-x: auto; } .table-wrap table { width: 100%; border-collapse: collapse; } .table-wrap caption { text-align: left; margin-bottom: 8px; font-weight: 700; } .table-wrap th, .table-wrap td { border: 1px solid #94a3b8; text-align: left; padding: 10px; }

Rendered output

Fruit prices
FruitPrice
Apple$3.00
Banana$1.50
Orange$2.00

Observe: The header labels identify columns, and collapsed cell borders form single lines.

Zebra stripes and hover

Add a distinct header, alternating rows and responsive overflow.

HTML

<div class="table-wrap"><table><caption>Fruit prices</caption><thead><tr><th scope="col">Fruit</th><th scope="col">Price</th></tr></thead><tbody><tr><td>Apple</td><td>$3.00</td></tr><tr><td>Banana</td><td>$1.50</td></tr><tr><td>Orange</td><td>$2.00</td></tr></tbody></table></div>

CSS

.table-wrap { overflow-x: auto; } .table-wrap table { width: 100%; min-width: 240px; border-collapse: collapse; } .table-wrap caption { text-align: left; margin-bottom: 8px; font-weight: 700; } .table-wrap th, .table-wrap td { border-bottom: 1px solid #cbd5e1; text-align: left; padding: 12px; } .table-wrap thead { background: #1d4ed8; color: white; } .table-wrap tbody tr:nth-child(even) { background: #eff6ff; } .table-wrap tbody tr:hover { background: #ccfbf1; }

Rendered output

Fruit prices
FruitPrice
Apple$3.00
Banana$1.50
Orange$2.00

Observe: The blue header and alternating rows improve scanning. On narrow widths, the wrapper scrolls.

Original CSS Table Styling — All Worked Examples

The original ProgramGuru table tutorial below is preserved with its progressive border, padding, striping, hover, header, alignment, responsive and complete-table demonstrations. This supplement retains the original source code and rendered output for each step.

HTML tables by default look basic and rigid. To create visually appealing, readable, and modern tables, CSS table styling is essential. Whether you're building a pricing chart, a data report, or a comparison table, CSS helps you bring structure and beauty to your data.

Basic Table Structure

Before diving into styling, let’s take a basic HTML table with three columns and five rows.

<div class="table-container">
  <table>
    <thead>
      <tr>
        <th>Fruit</th>
        <th>Color</th>
        <th>Price (per kg)</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Apple</td>
        <td>Red</td>
        <td>$3.00</td>
      </tr>
      <tr>
        <td>Banana</td>
        <td>Yellow</td>
        <td>$1.50</td>
      </tr>
      <tr>
        <td>Grapes</td>
        <td>Purple</td>
        <td>$2.80</td>
      </tr>
      <tr>
        <td>Orange</td>
        <td>Orange</td>
        <td>$2.00</td>
      </tr>
      <tr>
        <td>Watermelon</td>
        <td>Green</td>
        <td>$0.90</td>
      </tr>
    </tbody>
  </table>
</div>

FruitColorPrice (per kg)
AppleRed$3.00
BananaYellow$1.50
GrapesPurple$2.80
OrangeOrange$2.00
WatermelonGreen$0.90

1. Adding Basic Borders

Let’s start by giving the table a clean border using CSS:

table, th, td {
  border: 1px solid black;
  border-collapse: collapse;
}
FruitColorPrice (per kg)
AppleRed$3.00
BananaYellow$1.50
GrapesPurple$2.80
OrangeOrange$2.00
WatermelonGreen$0.90

Explanation: The border-collapse: collapse; property ensures that adjacent borders don’t double up — they merge into a single clean line.

2. Adding Padding and Spacing

To make text more readable, add padding to cells:

table, th, td {
  border: 1px solid black;
  border-collapse: collapse;
}
th, td {
  padding: 12px;
  text-align: left;
}
FruitColorPrice (per kg)
AppleRed$3.00
BananaYellow$1.50
GrapesPurple$2.80
OrangeOrange$2.00
WatermelonGreen$0.90

This increases whitespace within cells, enhancing clarity.

3. Zebra Striping Rows

Alternating row colors (also known as zebra striping) improve readability across rows of data.

table, th, td {
  border: 1px solid black;
  border-collapse: collapse;
}
th, td {
  padding: 12px;
  text-align: left;
}
tbody tr:nth-child(even) {
  background-color: #f2f2f2;
}
FruitColorPrice (per kg)
AppleRed$3.00
BananaYellow$1.50
GrapesPurple$2.80
OrangeOrange$2.00
WatermelonGreen$0.90

This subtle visual cue helps users follow data rows horizontally with ease.

4. Hover Effects for Interactivity

You can add a hover effect to highlight rows dynamically:

table, th, td {
  border: 1px solid black;
  border-collapse: collapse;
}
th, td {
  padding: 12px;
  text-align: left;
}
tbody tr:hover {
  background-color: #e0e0e0;
}
FruitColorPrice (per kg)
AppleRed$3.00
BananaYellow$1.50
GrapesPurple$2.80
OrangeOrange$2.00
WatermelonGreen$0.90

Users get feedback when they hover over a row — especially useful for clickable rows or admin dashboards.

5. Styling Headers

Headers can stand out using background color and text styling:

table, th, td {
  border: 1px solid black;
  border-collapse: collapse;
}
th, td {
  padding: 12px;
  text-align: left;
}
thead th {
  background-color: #4CAF50;
  color: white;
  font-weight: bold;
}
FruitColorPrice (per kg)
AppleRed$3.00
BananaYellow$1.50
GrapesPurple$2.80
OrangeOrange$2.00
WatermelonGreen$0.90

This helps distinguish headers from the rest of the table data visually and semantically.

6. Aligning Text

Column-wise alignment enhances data interpretation:

table, th, td {
  border: 1px solid black;
  border-collapse: collapse;
}
th, td {
  padding: 12px;
  text-align: left;
}
td:nth-child(2) {
  text-align: center;
}
td:nth-child(3) {
  text-align: right;
}
FruitColorPrice (per kg)
AppleRed$3.00
BananaYellow$1.50
GrapesPurple$2.80
OrangeOrange$2.00
WatermelonGreen$0.90

This is particularly helpful for numbers, prices, and data meant to be compared vertically.

7. Responsive Table Design

Standard tables are not mobile-friendly by default. Use the following approach for better responsiveness:

.table-container {
  overflow-x: auto;
}
<div class="table-container">
  <table>...</table>
</div>
FruitColorPrice (per kg)
AppleRed$3.00
BananaYellow$1.50
GrapesPurple$2.80
OrangeOrange$2.00
WatermelonGreen$0.90

This ensures your tables can be scrolled horizontally on smaller screens.

8. Table Width and Layout

Control table width and column behavior using:

table, th, td {
  border: 1px solid black;
  border-collapse: collapse;
}
table {
  width: 100%;
  table-layout: fixed;
}
th, td {
  word-wrap: break-word;
}
FruitColorPrice (per kg)
AppleRed$3.00
BananaYellow$1.50
GrapesPurple$2.80
OrangeOrange$2.00
WatermelonGreen$0.90

table-layout: fixed forces columns to distribute width evenly, preventing overflow issues.

9. Borderless Tables

To create a minimalist look:

table {
  border: none;
}
th, td {
  border: none;
  padding: 10px;
}
FruitColorPrice (per kg)
AppleRed$3.00
BananaYellow$1.50
GrapesPurple$2.80
OrangeOrange$2.00
WatermelonGreen$0.90

Use this for simple data listings where structure clarity isn’t critical.

10. Table with Complete Styling - 1

.table-container {
  overflow-x: auto;
}
table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}
thead th {
  background-color: #007BFF;
  color: white;
}
th, td {
  padding: 12px;
  text-align: left;
  border: 1px solid #ddd;
}
tbody tr:nth-child(even) {
  background-color: #f9f9f9;
}
tbody tr:hover {
  background-color: #f1f1f1;
}
FruitColorPrice (per kg)
AppleRed$3.00
BananaYellow$1.50
GrapesPurple$2.80
OrangeOrange$2.00
WatermelonGreen$0.90

Explain the result

Padding affects cell readability; collapsed borders avoid double edges; nth-child colors rows by position; an overflow container preserves table columns.

Compare the two examples: identify the selector, each changed property, and which visible part of the output proves that the CSS took effect.

Common mistakes to avoid

  • Never remove table headers just to make the layout look like separate cards.

  • Zebra striping should support—not replace—clear borders and typography.

Try it yourself

Add a third column and test the table at a 320px viewport; confirm that only the table wrapper scrolls.

Before changing the code, predict what will change. Then verify by checking the rendered result.

Check your understanding

Which property merges adjacent table borders?
Choose one answer. You can try again.

Answer and explanation

border-collapse: collapse

border-collapse:collapse uses the collapsed-border model.

What you should remember

Preserve table semantics while improving alignment, hierarchy, and responsive readability.

Revisit the rendered examples if the rule still feels abstract. Change one declaration at a time so you can connect cause and effect.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: CSS Card Designs →