Tables

Tables can be used to represent tabular data using rows and columns.

Overview #

Tables are opt-in, meaning you need to add the base class .table to a <table> element, then extend with our optional modifier classes or custom styles. All table styles are not inherited, meaning any nested tables can be styled independent from the parent.

# First Last Age
1 Johnathan Gates 25
2 Melissa Waters 27
3 Jack the Sleeper ???
HTML
<table class="table">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">First</th>
      <th scope="col">Last</th>
      <th scope="col" class="text-end">Age</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">1</th>
      <td>Johnathan</td>
      <td>Gates</td>
      <td class="text-end">25</td>
    </tr>
    <tr>
      <th scope="row">2</th>
      <td>Melissa</td>
      <td>Waters</td>
      <td class="text-end">27</td>
    </tr>
    <tr>
      <th scope="row">3</th>
      <td colspan="2">Jack the Sleeper</td>
      <td class="text-end">???</td>
    </tr>
  </tbody>
</table>

Accented tables #

Different styles are available for applying table accents (via modifier classes). They are generally best applied directly on the <table>, but some also work on individual rows and cells.

Accented tables Striped rows #

Use .table-striped to add zebra-striping to any table row within the <tbody>.

# First Last Age
1 Johnathan Gates 25
2 Melissa Waters 27
3 Richard Jones 38
HTML
<!-- Striped rows -->
<table class="table table-striped">
  ...
</table>

Accented tables Striped columns #

Use .table-striped-columns to add zebra-striping to any table column.

# First Last Age
1 Johnathan Gates 25
2 Melissa Waters 27
3 Richard Jones 38
HTML
<!-- Striped columns -->
<table class="table table-striped-columns">
  ...
</table>

Accented tables Hoverable rows #

Add .table-hover to enable a hover state on table rows within a <tbody>.

# First Last Age
1 Johnathan Gates 25
2 Melissa Waters 27
3 Richard Jones 38
HTML
<!-- Hoverable rows -->
<table class="table table-hover">
  ...
</table>

Accented tables Active tables #

Highlight a table row or cell by adding a .table-active class.

# First Last Age
1 Johnathan Gates 25
2 Melissa Waters 27
3 Jack the Sleeper ???
HTML
<!-- Active table row and cell -->
<table class="table">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">First</th>
      <th scope="col">Last</th>
      <th scope="col" class="text-end">Age</th>
    </tr>
  </thead>
  <tbody>
    <tr class="table-active">
      <th scope="row">1</th>
      <td>Johnathan</td>
      <td>Gates</td>
      <td class="text-end">25</td>
    </tr>
    <tr>
      <th scope="row">2</th>
      <td>Melissa</td>
      <td>Waters</td>
      <td class="text-end">27</td>
    </tr>
    <tr>
      <th scope="row">3</th>
      <td class="table-active" colspan="2">Jack the Sleeper</td>
      <td class="text-end">???</td>
    </tr>
  </tbody>
</table>

Variants #

Use the .table-{variant} contextual classes to apply table variants, where the {variant} can be primary, secondary, success, danger, warning, info, light, or dark. Note that these classes can be used on cells, rows, head, body, foot, or the actual table. Generally speaking, however, it is recommended that they are used sparingly on cells and rows for the maximum visual impact. Also note, all of the above accent styles will work with table variants.

Given below is an example of using the contextual classes on table cells (<td> or <th>).

# Name Maths Science English
1 Jeff 84 92 83
2 Jonah 100 77 78
3 Nicole 84 86 49
4 Yelena 91 80 79
5 Yusuf 88 88 67
HTML
<!-- Table variants on cells -->
<table class="table table-hover">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">Name</th>
      <th scope="col">Maths</th>
      <th scope="col">Science</th>
      <th scope="col">English</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">1</th>
      <td>Jeff</td>
      <td>84</td>
      <td class="table-primary">92</td>
      <td>83</td>
    </tr>
    <tr>
      <th scope="row">2</th>
      <td>Jonah</td>
      <td class="table-success">100</td>
      <td>77</td>
      <td>78</td>
    </tr>
    <tr>
      <th scope="row">3</th>
      <td>Nicole</td>
      <td>84</td>
      <td>86</td>
      <td class="table-danger">49</td>
    </tr>
    <tr>
      <th scope="row">4</th>
      <td>Yelena</td>
      <td class="table-primary">91</td>
      <td>80</td>
      <td>79</td>
    </tr>
    <tr>
      <th scope="row">5</th>
      <td>Yusuf</td>
      <td>88</td>
      <td>88</td>
      <td class="table-warning">67</td>
    </tr>
  </tbody>
</table>

Here's another example of using the contextual classes on table rows.

# Name Department Score
1 Tim Marketing 8
2 Jenna Engineering 9
3 Richard Sales 6
4 Kim Engineering 4
5 Adam Sales 7
HTML
<!-- Table variants on rows -->
<table class="table table-hover">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">Name</th>
      <th scope="col">Department</th>
      <th scope="col">Score</th>
    </tr>
  </thead>
  <tbody>
    <tr class="table-primary">
      <th scope="row">1</th>
      <td>Tim</td>
      <td>Marketing</td>
      <td>8</td>
    </tr>
    <tr class="table-success">
      <th scope="row">2</th>
      <td>Jenna</td>
      <td>Engineering</td>
      <td>9</td>
    </tr>
    <tr>
      <th scope="row">3</th>
      <td>Richard</td>
      <td>Sales</td>
      <td>6</td>
    </tr>
    <tr class="table-danger">
      <th scope="row">4</th>
      <td>Kim</td>
      <td>Engineering</td>
      <td>4</td>
    </tr>
    <tr>
      <th scope="row">5</th>
      <td>Adam</td>
      <td>Sales</td>
      <td>7</td>
    </tr>
  </tbody>
</table>

How do the accented tables and variants work? #

For the accented tables (striped rows, striped columns, hoverable rows, and active tables), we used some techniques to make these effects work for all our table variants:

  • We start by setting the background of a table cell with the --bs-table-bg custom property. All table variants then set that custom property to colorize the table cells. This way, we don't get into trouble if semi-transparent colors are used as table backgrounds.
  • Then we add an inset box shadow on the table cells with box-shadow: inset 0 0 0 9999px var(--bs-table-bg-state, var(--bs-table-bg-type, var(--bs-table-accent-bg))) to layer on top of any specified background-color. It uses custom cascade to override the box-shadow, regardless the CSS specificity. Because we use a huge spread and no blur, the color will be monotone. Since --bs-table-accent-bg is set to transparent by default, we don't have a default box shadow.
  • When either .table-striped, .table-striped-columns, .table-hover or .table-active classes are added, either --bs-table-bg-type or --bs-table-bg-state (by default set to initial) are set to a semi-transparent color (--bs-table-striped-bg, --bs-table-active-bg or --bs-table-hover-bg) to colorize the background and override default --bs-table-accent-bg.

Table borders #

Apply or remove borders to tables using the table border classes. Please note, you can also use border utilities on tables along with these classes.

Table borders Bordered tables #

Add .table-bordered for borders on all sides of the table and cells.

# First Last Age
1 Johnathan Gates 25
2 Melissa Waters 27
3 Richard Jones 38
HTML
<!-- Bordered table -->
<table class="table table-bordered">
  ...
</table>

Table borders Tables without borders #

Add .table-borderless for a table without borders.

# First Last Age
1 Johnathan Gates 25
2 Melissa Waters 27
3 Richard Jones 38
HTML
<!-- Borderless table -->
<table class="table table-borderless">
  ...
</table>

Small tables #

Add .table-sm to make any .table more compact by reducing all cell padding.

# First Last Age
1 Johnathan Gates 25
2 Melissa Waters 27
3 Richard Jones 38
HTML
<!-- Small table -->
<table class="table table-sm">
  ...
</table>

Table group dividers #

Add a thicker border, darker between table groups—<thead>, <tbody>, and <tfoot>—with .table-group-divider. Customize the color by changing the border-top-color property.

# First Last Age
1 Johnathan Gates 25
2 Melissa Waters 27
3 Richard Jones 38
HTML
<!-- Table group divider -->
<table class="table">
  <thead>
    ...
  </thead>
  <tbody class="table-group-divider">
    ...
  </tbody>
</table>

Vertical alignment #

Table cells of <thead> are always vertical aligned to the bottom. Table cells in <tbody> inherit their alignment from <table> and are aligned to the top by default. Use the vertical align classes to re-align where needed.

Heading Heading Heading
Middle
(From table)
Middle
(From table)
Bottom
(From row)
Bottom
(From row)
Middle
(From table)
Top
(From cell)
HTML
<!-- Vertical alignment -->
<table class="table table-bordered align-middle">
  <thead>
    ...
  </thead>
  <tbody>
    <tr>
      ...
    </tr>
    <tr class="align-bottom">
      ...
    </tr>
    <tr>
      <td>...</td>
      <td>...</td>
      <td class="align-top">...</td>
    </tr>
  </tbody>
</table>

Nesting #

Border styles, active styles, and table variants are not inherited by nested tables.

# First Last Age
1 Johnathan Gates 25
# Department Code
A Marketing MKT
B Business development BUS
2 Melissa Waters 27
HTML
<!-- Nested tables -->
<table class="table table-striped">
  <thead>
    ...
  </thead>
  <tbody>
    ...
    <tr>
      <td colspan="4">
        <table class="table mb-0">
          ...
        </table>
      </td>
    </tr>
    ...
  </tbody>
</table>

Nesting How nesting works #

To prevent any styles from leaking to nested tables, we use the child combinator (>) selector in our CSS. Since we need to target all the td and th tags in the thead, tbody, and tfoot, our selector would look pretty long without it. As such, we use the rather odd looking .table > :not(caption) > * > * selector to target all td and th tags of the .table, but none of any potential nested tables.

Note that if you add <tr> tags as direct children of a table, those <tr> tags will be wrapped in a <tbody> by default, thus making our selectors work as intended.

Anatomy #

Tables are made up of <thead>, <tbody>, and <tfoot> tags. They can also be labeled using a <caption> placed inside the <table>.

Anatomy Table head #

The following example shows a table head marked visually using the .table-secondary class.

# First Last Age
1 Johnathan Gates 25
2 Melissa Waters 27
3 Richard Jones 38
HTML
<!-- Table head -->
<table class="table">
  <thead class="table-secondary">
    ...
  </thead>
  <tbody>
    ...
  </tbody>
</table>

Anatomy Table foot #

The next example shows a table foot, along with the head and body.

# First Last Age
1 Johnathan Gates 25
2 Melissa Waters 27
3 Richard Jones 38
Footer Footer Footer Footer
HTML
<!-- Table foot -->
<table class="table">
  <thead class="table-secondary">
    ...
  </thead>
  <tbody>
    ...
  </tbody>
  <tfoot>
    ...
  </tfoot>
</table>

Anatomy Captions #

A <caption> functions like a heading for a table. It helps users with screen readers to find a table and understand what it's about and decide if they want to read it.

List of employees
# First Last Age
1 Johnathan Gates 25
2 Melissa Waters 27
3 Richard Jones 38
HTML
<!-- Table caption -->
<table class="table">
  <caption>List of employees</caption>
  <thead>
    ...
  </thead>
  <tbody>
    ...
  </tbody>
</table>

You can also put the <caption> on the top of the table with .caption-top.

List of employees
# First Last Age
1 Johnathan Gates 25
2 Melissa Waters 27
3 Richard Jones 38
HTML
<!-- Table caption on top -->
<table class="table caption-top">
  <caption class="border-bottom">List of employees</caption>
  <thead>
    ...
  </thead>
  <tbody>
    ...
  </tbody>
</table>

Responsive tables #

Responsive tables allow tables to be scrolled horizontally with ease. Make any table responsive by wrapping a .table with the following:

  • .table-responsive — across all viewports
  • .table-responsive-{sm|md|lg|xl|xxl} — breakpoint specific

Please note, you may have to set a width to the containing wrapper.

# Heading Heading Heading Heading Heading Heading Heading Heading Heading
1 Item Item Item Item Item Item Item Item Item
2 Item Item Item Item Item Item Item Item Item
3 Item Item Item Item Item Item Item Item Item
HTML
<!-- Responsive table -->
<div class="card table-responsive specific-w-300 mw-100 mx-auto rounded-0">
  <table class="table">
    ...
  </table>
</div>
Up next
Figures

Help us grow

Our main goal is to make Halfmoon the go-to framework for building websites, dashboards and tools. If you believe in our mission, consider becoming a sponsor and help us grow.

You can email us directly if you have any queries. We are always happy to answer.

Subscribe for updates

We will notify you when the framework gets a substantial update. No spam ever.

Follow us on Twitter so that you can stay updated that way.