Question
Is it possible to add space between two rows of an HTML table using CSS? I tried applying border-spacing: 5em to a table-row selector, but it did not work:
tr.classname {
border-spacing: 5em;
}
What is the correct way to create spacing between table rows?
Short Answer
You will learn why border-spacing must be applied to the <table> element, why border-collapse affects it, and when padding or other techniques are better choices for table row separation.
Concept
HTML tables use a special layout model. A <tr> is a table row, but it does not control the gaps between table cells or rows.
The CSS property border-spacing controls the distance between cells in a table. Because it describes the table grid as a whole, it belongs on the <table> element, not on <tr> or <td>.
For border-spacing to work, the table must use the separate-border model:
table {
border-collapse: separate;
border-spacing: 0 1rem;
}
If the table has border-collapse: collapse, its borders are merged and border-spacing has no visible effect.
This matters in real interfaces because tables are often used for invoices, reports, admin lists, schedules, and other truly tabular data. Understanding which element owns a layout property helps you choose CSS that the browser can apply correctly.
Mental Model
Think of a table as a tray holding a grid of cups.
- The
<table>is the entire tray. - A
<tr>is one horizontal line of cups. - A
<td>is one cup.
border-spacing changes the empty space built into the tray grid, so it must be set on the tray (<table>). A single row cannot decide how far away every other row should be.
Syntax and Examples
Use border-spacing on the table:
table {
border-collapse: separate;
border-spacing: horizontal vertical;
}
The first value is horizontal space between columns. The second value is vertical space between rows.
<table class="orders">
<tr>
<td>Order #1001</td>
<td>Processing</td>
</tr>
<tr>
<td>Order #1002</td>
<td>Shipped</td>
</tr>
</table>
.orders {
border-collapse: separate;
border-spacing: 0 1rem;
}
.orders td {
padding: 0.75rem;
background: #f3f4f6;
}
0 1rem means:
0: no extra space between columns.1rem: oneremof extra space between rows.
If you want the same gap in both directions, use one value:
.orders {
border-spacing: 1rem;
}
The attempted selector does not work because border-spacing is not a property that a tr uses to position other rows:
/* This does not create row gaps. */
tr.classname {
border-spacing: 5em;
}
Step by Step Execution
Consider this table:
<table class="schedule">
<tr>
<td>09:00</td>
<td>Team meeting</td>
</tr>
<tr>
<td>11:00</td>
<td>Code review</td>
</tr>
</table>
And this CSS:
.schedule {
border-collapse: separate;
border-spacing: 0 12px;
}
.schedule td {
padding: 8px;
background: white;
}
What happens:
- The browser reads
.scheduleand identifies the<table>. border-collapse: separatetells the browser to keep cell borders and cell gaps separate.border-spacing: 0 12pxcreates no horizontal gap and a12pxvertical gap.- The first row is laid out normally.
- Before the next row, the table grid leaves
12pxof space. - Padding inside each
<td>adds room inside the cells; it does not create the gap between rows.
If border-collapse: collapse were used instead, step 3 would not produce a gap.
Real World Use Cases
border-spacing is useful when table rows should look like separate visual items:
- Admin dashboards: Give each user, order, or support ticket row breathing room.
- Financial reports: Separate transaction rows without adding heavy borders.
- Booking schedules: Make time slots easier to scan.
- Email-safe or legacy table layouts: Where a real table is already required.
- Comparison tables: Add both horizontal and vertical separation between plan details.
For data that is not naturally tabular, such as a stack of product cards, use Flexbox or CSS Grid instead of a table.
Real Codebase Usage
In production code, developers usually combine row spacing with cell styling:
.data-table {
width: 100%;
border-collapse: separate;
border-spacing: 0 0.5rem;
}
.data-table td,
.data-table th {
padding: 0.75rem 1rem;
background: white;
}
.data-table tbody tr {
box-shadow: 0 1px 3px rgb(0 0 0 / 10%);
}
Common project patterns include:
- Use
border-spacing: 0 <value>to separate rows while keeping columns aligned without gaps. - Apply
paddingtotdandthfor readable content. - Apply background colors to cells when rows need to resemble individual cards, because a row's background may not visually fill the spaces as expected.
- Reset inherited table styles explicitly. A CSS framework or browser stylesheet may set
border-collapse: collapse. - Use a class on the table, such as
.data-table, rather than styling every table globally.
Common Mistakes
Applying border-spacing to <tr>
/* Incorrect for row gaps */
tr.classname {
border-spacing: 5em;
}
border-spacing belongs on the table:
table.classname {
border-spacing: 0 5em;
}
Forgetting border-collapse: separate
.orders {
border-collapse: collapse;
border-spacing: 0 1rem; /* Has no effect */
}
Fix it by using separate:
.orders {
border-collapse: separate;
border-spacing: 0 1rem;
}
Using margin on table rows
tr {
margin-bottom: 1rem;
}
Margins do not reliably create row spacing because table rows follow table layout rules. Prefer border-spacing for an actual table.
Using only one value unintentionally
table {
border-spacing: 1rem;
}
This adds 1rem in both directions. For row-only spacing, use two values:
table {
border-spacing: 0 1rem;
}
Confusing padding with row separation
Padding makes each cell larger, but adjacent rows still touch when there is no border spacing. Use padding for internal room and border-spacing for external gaps.
Comparisons
| Technique | Best use | Key behavior |
|---|---|---|
border-spacing on table | Gaps between rows or cells in a real table | Requires border-collapse: separate |
padding on td / th | More room inside cells | Does not create a gap between adjacent rows |
border-bottom on cells | Visual row dividers | Draws a line instead of empty space |
margin on tr | Usually avoid | Does not work reliably in table layout |
Flexbox or Grid gap | Card lists and non-tabular layouts | Use when the content is not a semantic table |
border-collapse also changes the result:
| Value | Result |
|---|---|
separate | Cells can have spacing between them; border-spacing works |
collapse | Adjacent borders merge; border-spacing is ignored |
Cheat Sheet
/* Vertical gaps only */
table {
border-collapse: separate;
border-spacing: 0 1rem;
}
/* Horizontal and vertical gaps */
table {
border-collapse: separate;
border-spacing: 0.5rem 1rem;
}
/* Same gap in both directions */
table {
border-collapse: separate;
border-spacing: 1rem;
}
- Apply
border-spacingto<table>, not<tr>. - Syntax:
border-spacing: horizontal vertical;. - A single value applies to both directions.
border-collapse: separateis required.- Use
paddingontdandthfor space inside cells. - Do not rely on margins on table rows.
FAQ
Why is border-spacing not working on my table?
Check whether the table or a CSS framework sets border-collapse: collapse. Set border-collapse: separate on the same table.
Can I add space only between table rows?
Yes. Use a horizontal value of 0 and a vertical value such as 12px:
table { border-spacing: 0 12px; }
Can I use margin-bottom on a <tr>?
It is not a reliable way to space table rows. Table rows are laid out by the table formatting model. Use border-spacing instead.
Does border-spacing add space around the outside of the table?
It can create space between the table edge and its first or last cells as part of the separate-border model. Use table or container padding if you need precise outer spacing.
Should I use a table for a list of cards?
Only use a table for data with row-and-column relationships. For cards, navigation items, or general page layout, use Flexbox or Grid and their gap property.
Can I use pixels instead of em or rem?
Yes. px, em, rem, and other valid CSS length units can be used. rem is often convenient for scalable interface spacing.
Mini Project
Description
Create a compact order table where each order appears as a visually separate row. This pattern is common in dashboards and order-management screens, while preserving correct table semantics for tabular data.
Goal
Build a two-column orders table with vertical space between rows and readable cell padding.
Requirements
Use a semantic <table> with a header and at least three order rows.
Apply vertical row spacing without adding horizontal column spacing.
Keep table borders in the separate-border model.
Add padding and a background color to the table cells.
Use valid CSS selectors scoped to the table.
Keep learning
Related questions
Add a Favicon to a Static HTML Page
Learn how to add a favicon to static HTML pages, use correct paths and icon formats, and troubleshoot browser caching and local-file issues.
Allow Only Numeric Input (0-9) in HTML Input Using jQuery
Learn how to allow only digits 0-9 in an HTML input using jQuery, with examples, validation tips, common mistakes, and best practices.
Apply CSS !important with jQuery .css()
Learn why jQuery .css() cannot set !important and how to use CSSStyleDeclaration.setProperty() to apply inline important styles safely.