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.

ClassCSSDescription
bs4pxborder-spacing: 4px4px spacing
bs8pxborder-spacing: 8px8px spacing
bs16pxborder-spacing: 16px16px spacing
bs2remborder-spacing: 2rem20px 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

A1B1
A2B2

Borders merge into one and no spacing is possible.

separate + bs4px

A1B1
A2B2

Each cell keeps its own border and they sit 4px apart.

separate + bs2rem

A1B1
A2B2

Widen the spacing and every cell reads as its own tile.

collapse + bs2rem

A1B1
A2B2

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.