Question

CSS Table Row Spacing: Using border-spacing Correctly

csshtml

Question

Is it possible to add space between two rows in an HTML table using CSS? I tried applying border-spacing to a table row, but it has no effect:

tr.classname {
  border-spacing: 5em;
}

What is the correct way to create vertical space between table rows?

Short Answer

You will learn why border-spacing does not work on <tr> elements, how to apply it correctly to a <table>, and when other approaches such as cell padding or borders are more appropriate.

Concept

border-spacing controls the empty space between cells in a table. It is a property of the table's layout, so it must be applied to the <table> element—not to individual <tr> rows or <td> cells.

For border-spacing to work, the table must use the separate border model:

table {
  border-collapse: separate;
  border-spacing: 0 1rem;
}

The first value controls horizontal spacing between columns, and the second controls vertical spacing between rows.

This matters because HTML tables do not behave like normal block layouts. Elements such as <div> can commonly use margin and gap, but table rows follow the browser's table-layout rules. Using the table-specific properties produces predictable results.

Mental Model

Think of a table as a tray holding a grid of cells.

  • The <table> is the entire tray.
  • Each <tr> is one line of compartments.
  • Each <td> or <th> is an individual compartment.

border-spacing changes the distance between compartments across the whole tray. A single row cannot decide how far away the next row sits, so putting border-spacing on <tr> has no effect.

Take Quiz

Syntax and Examples

Apply border-spacing to the <table> element:

<table class="orders">
  <tr>
    <th>Order</th>
    <th>Status</th>
  </tr>
  <tr>
    <td>#1042</td>
    <td>Shipped</td>
  </tr>
  <tr>
    <td>#1043</td>
    <td>Processing</td>
  </tr>
</table>
.orders {
  border-collapse: separate;
  border-spacing: 0 1rem;
}

.orders th,
.orders td {
  padding: 0.75rem;
  background: #f4f4f4;
}

border-spacing: 0 1rem means:

  • 0: no horizontal space between columns.
  • 1rem: one rem of vertical space between rows.

You can also use one value for both directions:

.orders {
  border-spacing: 1rem;
}

This adds 1rem of space both between columns and between rows.

Step by Step Execution

Consider this example:

<table class="schedule">
  <tr><td>09:00</td><td>Planning</td></tr>
  <tr><td>10:00</td><td>Development</td></tr>
</table>
.schedule {
  border-collapse: separate;
  border-spacing: 0 12px;
}

.schedule td {
  padding: 8px;
  background: white;
}

What happens:

  1. The browser recognizes .schedule as a table.
  2. border-collapse: separate tells the browser to keep each cell's border area separate rather than merging neighboring borders.
  3. border-spacing: 0 12px sets horizontal spacing to 0 and vertical spacing to 12px.
  4. The browser places 12 pixels of empty space between the first row's cells and the second row's cells.
  5. The padding inside each <td> creates space around the text inside each cell. It does not create the gap between rows.

Real World Use Cases

Vertical table spacing is useful when table rows should look like separate items rather than one continuous spreadsheet grid.

Examples include:

  • Admin dashboards: Separate customer, invoice, or order rows visually.
  • Finance tables: Make transaction entries easier to scan.
  • Booking schedules: Distinguish appointments or events.
  • Email-style lists: Present each row as a compact card while preserving table semantics.
  • Responsive reports: Keep dense data readable without adding heavy borders.
Take Quiz

Real Codebase Usage

In production code, developers choose the spacing technique based on the desired visual design.

A common "card row" pattern uses vertical border-spacing plus cell backgrounds:

.user-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0 0.75rem;
}

.user-table td {
  padding: 1rem;
  background: #fff;
}

.user-table td:first-child {
  border-radius: 0.5rem 0 0 0.5rem;
}

.user-table td:last-child {
  border-radius: 0 0.5rem 0.5rem 0;
}

For traditional data grids, teams often use collapsed borders instead:

.data-table {
  border-collapse: collapse;
}

.data-table tr {
  border-bottom: 1px solid #d1d5db;
}

Use border-spacing when you want visible gaps. Use collapsed borders when you want a continuous grid with dividing lines.

Common Mistakes

Applying border-spacing to <tr>

This does not work because rows do not control table border spacing:

/* Does not create row gaps */
tr {
  border-spacing: 1rem;
}

Apply it to the table instead:

table {
  border-collapse: separate;
  border-spacing: 0 1rem;
}

Leaving border-collapse: collapse enabled

border-spacing has no effect when borders are collapsed:

table {
  border-collapse: collapse;
  border-spacing: 0 1rem; /* Ignored */
}

Fix it with:

table {
  border-collapse: separate;
  border-spacing: 0 1rem;
}

Using margin on table rows

Margins on <tr> are not a dependable way to space rows because rows use table layout rules:

tr {
  margin-bottom: 1rem; /* Do not rely on this */
}

Use border-spacing, a row border, or a different layout such as CSS Grid when the content is not truly tabular.

Confusing padding with row spacing

Padding makes cells taller, but it does not create an empty gap between rows:

td {
  padding: 1rem;
}

Use padding for internal cell space and border-spacing for external space between cells and rows.

Comparisons

TechniqueWhere it is appliedBest forImportant note
border-spacing<table>Visible gaps between rows or columnsRequires border-collapse: separate
padding<td> and <th>More room inside cellsIncreases row height; it does not create a true gap
border-bottomUsually <tr> or cellsDivider lines in a continuous tableCommon with border-collapse: collapse
marginBlock elementsSpacing normal page sectionsNot reliable on <tr> elements
CSS gapFlexbox or Grid containersNon-tabular card/list layoutsNot a standard solution for traditional table row layout

Use a real <table> when values have row-and-column relationships, such as reports or schedules. Use Flexbox or Grid when you are building a visual list of independent cards.

Take Quiz

Cheat Sheet

/* Space rows only */
table {
  border-collapse: separate;
  border-spacing: 0 1rem;
}

/* Space columns and rows equally */
table {
  border-collapse: separate;
  border-spacing: 1rem;
}

/* Space columns by 8px and rows by 16px */
table {
  border-collapse: separate;
  border-spacing: 8px 16px;
}
  • Apply border-spacing to <table>, not <tr>.
  • One value applies to both horizontal and vertical spacing.
  • Two values mean horizontal vertical.
  • border-spacing works only with border-collapse: separate.
  • Use padding for space inside cells.
  • Do not rely on margins for table-row spacing.

FAQ

Why is border-spacing not working on my table?

It must be placed on the <table> element. Also check that border-collapse is set to separate, not collapse.

Can I add space only between table rows?

Yes. Set the horizontal value to zero and provide a vertical value:

table { border-spacing: 0 12px; }

Does border-spacing add space around the outside of the table?

It can create spacing between the table edge and its first or last cells in the separate border model. Use a wrapper's padding when you need precise outer spacing.

Can I use margin-bottom on a <tr>?

Do not rely on it. Table rows are laid out using table rules, and margins do not consistently create the intended row gap.

Should I use border-spacing or cell padding?

Use border-spacing for empty space between rows or columns. Use cell padding for room inside a cell around its content.

Can border-spacing use em or rem units?

Yes. Standard CSS length units such as px, em, rem, and %-independent lengths can be used. For example, border-spacing: 0 0.75rem;.

What if my layout is not really tabular data?

Use semantic elements such as <article> or <div> with CSS Grid or Flexbox. Those layouts support gap directly and are often better for card lists.

Take Quiz

Mini Project

Description

Build a small order table where each order appears as a visually distinct row. This demonstrates vertical table spacing while keeping the HTML structure semantic for row-and-column data.

Goal

Create a table with a 12-pixel gap between order rows and no gap between its columns.

Requirements

Use a semantic <table> with a header row and at least three order rows. Apply vertical spacing between rows using border-spacing. Ensure the table uses the separate border model. Add padding inside cells so the content remains readable. Use a background color for data cells so the row gaps are visible.

Take Quiz

Keep learning

Related questions

View more