border-spacing
Sets the spacing between table cells. It only works when the table uses border-collapse: separate, where each cell keeps its own border, and it is the only way to make a table grid read as separated cards.
Class List
Use the bs prefix with a unit.
| Class | CSS | Description |
|---|---|---|
bs4px | border-spacing: 4px | 4px spacing |
bs8px | border-spacing: 8px | 8px spacing |
bs16px | border-spacing: 16px | 16px spacing |
bs2rem | border-spacing: 2rem | 20px spacing (2rem) |
Live Demo
All four tables have identical cells and identical borders. Only the border-collapse value and the spacing differ. The last one demonstrates the classic mistake.
collapse — bcc
| A1 | B1 |
| A2 | B2 |
Borders merge into one and no spacing is possible.
separate + bs4px
| A1 | B1 |
| A2 | B2 |
Each cell keeps its own border and they sit 4px apart.
separate + bs2rem
| A1 | B1 |
| A2 | B2 |
Widen the spacing and every cell reads as its own tile.
collapse + bs2rem
| A1 | B1 |
| A2 | B2 |
The spacing is ignored: border-spacing does nothing while collapsed.
<!-- Collapsed: shared borders, no spacing possible -->
<table class="bcc">...</table>
<!-- Separate: every cell keeps its own border, spacing applies -->
<table class="bcs bs4px">...</table>
<table class="bcs bs2rem">...</table>
<!-- Collapsed again: bs2rem is silently ignored -->
<table class="bcc bs2rem">...</table>Class Details
bs4pxborder-spacing: 4px
The tightest useful value. It is just enough to stop adjacent borders from doubling up, while the grid still reads as a single table.
<!-- Just enough air to see doubled borders as a seam -->
<table class="bcs bs4px w100p">
<tr><td class="b1pxsolid27272A p12px">Cell</td></tr>
</table>bs8pxborder-spacing: 8px
A sensible default for separating data rows into card-like bands. Give each row a background and the spacing acts as the divider.
<!-- Card-like rows in a data table -->
<table class="bcs bs8px w100p">
<tr>
<td class="bg18181B br6px p16px">Row as a card</td>
</tr>
</table>bs16pxbs2remborder-spacing: 16px / 2rem
At larger values the table stops reading as a table and becomes a tile grid. Use it where each cell should be its own card, such as calendars or pricing comparisons.
<!-- Calendar grid: each day is its own tile -->
<table class="bcs bs16px w100p">
<tr>
<td class="bg18181B br8px p16px h8rem vat">1</td>
<td class="bg18181B br8px p16px h8rem vat">2</td>
</tr>
</table>Horizontal and vertical spacing can differ
The CSS property accepts two values, one for horizontal and one for vertical spacing. Atomic classes cover the single-value form, so set the two-value version in your own project CSS if you need it.
Practical Example
<!-- Table cell gap -->
<table class="bcs bs8px">
<tr>
<td class="bg18181B p16px">Cell 1</td>
<td class="bg18181B p16px">Cell 2</td>
</tr>
<tr>
<td class="bg18181B p16px">Cell 3</td>
<td class="bg18181B p16px">Cell 4</td>
</tr>
</table>Pricing tables, where each column has to look like its own card, are the classic use case.
<!-- Pricing comparison: each plan column reads as a separate card,
which only works because the table is not collapsed -->
<table class="bcs bs16px w100p">
<thead>
<tr>
<th class="p16px tal fs12px ttu ls0-05em cA1A1AA"></th>
<th class="bg18181B br8px p16px cFAFAFA">Free</th>
<th class="bg6366F1 br8px p16px cFFFFFF">Pro</th>
</tr>
</thead>
<tbody>
<tr>
<td class="p16px fs13px c71717A">Projects</td>
<td class="bg18181B br8px p16px tac cFAFAFA">3</td>
<td class="bg1E1E2E br8px p16px tac cFAFAFA">Unlimited</td>
</tr>
</tbody>
</table>Tips and Pitfalls
bs prefix overlap
The bs prefix is shared by border-spacing and box-shadow patterns. Values with a unit, such as bs8px or bs2rem, are read as border-spacing.
Without border-collapse: separate it is ignored
This property only works together with bcs. Reset stylesheets and shared table styles very often set bcc, so if the spacing does nothing, check that first.
It also pads the outer edge of the table
Border spacing is inserted between the table border and the first cells as well as between the cells themselves. That is why a spaced table looks subtly inset.
Margins on cells are ignored
Table cells do not honour margin at all. Spacing between cells can only come from border-spacing, and inner breathing room has to come from padding.