React Bootstrap Table Component

Table with Bootstrap Styling

Bootstrap 5 components designed for React.js

This component is part of the CoreUI for React.js UI components library, which offers all Bootstrap components designed to work seamlessly with React.js.

If you want to use Bootstrap 5 in a React.js environment while also needing advanced components that Bootstrap does not offer and dedicated developer support, then this library is the best solution for you.

Learn how to use CoreUI’s React Bootstrap Table component to build responsive, feature-rich tables styled with Bootstrap in your React app.

How to use React Bootstrap Table component

The <CTable> component with Bootstrap theming lets you build responsive and accessible React tables using CoreUI components. Define structure manually or use the columns and items API for easier table generation.

import { CTable } from '@coreui/react'

export const TableExample = (props) => {
  const columns = [
    {
      key: 'id',
      label: '#',
      _props: { scope: 'col' },
    },
    {
      key: 'class',
      _props: { scope: 'col' },
    },
    {
      key: 'heading_1',
      label: 'Heading',
      _props: { scope: 'col' },
    },
    {
      key: 'heading_2',
      label: 'Heading',
      _props: { scope: 'col' },
    },
  ]
  const items = [
    {
      id: 1,
      class: 'Mark',
      heading_1: 'Otto',
      heading_2: '@mdo',
      _cellProps: { id: { scope: 'row' } },
    },
    {
      id: 2,
      class: 'Jacob',
      heading_1: 'Thornton',
      heading_2: '@fat',
      _cellProps: { id: { scope: 'row' } },
    },
    {
      id: 3,
      class: 'Larry the Bird',
      heading_2: '@twitter',
      _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } },
    },
  ]
  return <CTable columns={columns} items={items} {...props} />
}
import { CTable } from '@coreui/react'

export const TableExample = (props) => {
  const columns = [
    {
      key: 'id',
      label: '#',
      _props: { scope: 'col' },
    },
    {
      key: 'class',
      _props: { scope: 'col' },
    },
    {
      key: 'heading_1',
      label: 'Heading',
      _props: { scope: 'col' },
    },
    {
      key: 'heading_2',
      label: 'Heading',
      _props: { scope: 'col' },
    },
  ]
  const items = [
    {
      id: 1,
      class: 'Mark',
      heading_1: 'Otto',
      heading_2: '@mdo',
      _cellProps: { id: { scope: 'row' } },
    },
    {
      id: 2,
      class: 'Jacob',
      heading_1: 'Thornton',
      heading_2: '@fat',
      _cellProps: { id: { scope: 'row' } },
    },
    {
      id: 3,
      class: 'Larry the Bird',
      heading_2: '@twitter',
      _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } },
    },
  ]
  return <CTable columns={columns} items={items} {...props} />
}

In version 4.3.0 we introduced a new way to create a table, similarly to our Smart Table component.

const columns = [
  {
    key: 'id',
    label: '#',
    _props: { scope: 'col' },
  },
  {
    key: 'class',
    _props: { scope: 'col' },
  },
  {
    key: 'heading_1',
    label: 'Heading',
    _props: { scope: 'col' },
  },
  {
    key: 'heading_2',
    label: 'Heading',
    _props: { scope: 'col' },
  },
]
const items = [
  {
    id: 1,
    class: 'Mark',
    heading_1: 'Otto',
    heading_2: '@mdo',
    _cellProps: { id: { scope: 'row' } },
  },
  {
    id: 2,
    class: 'Jacob',
    heading_1: 'Thornton',
    heading_2: '@fat',
    _cellProps: { id: { scope: 'row' } },
  },
  {
    id: 3,
    class: 'Larry the Bird',
    heading_2: '@twitter',
    _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } },
  },
]
return <CTable columns={columns} items={items} />

You can also put all table components together manually as hitherto.

<CTable>
  <CTableHead>
    <CTableRow>
      <CTableHeaderCell scope="col">#</CTableHeaderCell>
      <CTableHeaderCell scope="col">Class</CTableHeaderCell>
      <CTableHeaderCell scope="col">Heading</CTableHeaderCell>
      <CTableHeaderCell scope="col">Heading</CTableHeaderCell>
    </CTableRow>
  </CTableHead>
  <CTableBody>
    <CTableRow>
      <CTableHeaderCell scope="row">1</CTableHeaderCell>
      <CTableDataCell>Mark</CTableDataCell>
      <CTableDataCell>Otto</CTableDataCell>
      <CTableDataCell>@mdo</CTableDataCell>
    </CTableRow>
    <CTableRow>
      <CTableHeaderCell scope="row">2</CTableHeaderCell>
      <CTableDataCell>Jacob</CTableDataCell>
      <CTableDataCell>Thornton</CTableDataCell>
      <CTableDataCell>@fat</CTableDataCell>
    </CTableRow>
    <CTableRow>
      <CTableHeaderCell scope="row">3</CTableHeaderCell>
      <CTableDataCell colSpan={2}>Larry the Bird</CTableDataCell>
      <CTableDataCell>@twitter</CTableDataCell>
    </CTableRow>
  </CTableBody>
</CTable>

Both methods produce the same html code.

Variants

Use contextual classes to color React tables, table rows or individual cells.

<CTable>
  <CTableHead>
    <CTableRow>
      <CTableHeaderCell scope="col">Class</CTableHeaderCell>
      <CTableHeaderCell scope="col">Heading</CTableHeaderCell>
      <CTableHeaderCell scope="col">Heading</CTableHeaderCell>
    </CTableRow>
  </CTableHead>
  <CTableBody>
    <CTableRow>
      <CTableHeaderCell scope="row">Default</CTableHeaderCell>
      <CTableDataCell>Cell</CTableDataCell>
      <CTableDataCell>Cell</CTableDataCell>
    </CTableRow>
    <CTableRow theme="primary">
      <CTableHeaderCell scope="row">Primary</CTableHeaderCell>
      <CTableDataCell>Cell</CTableDataCell>
      <CTableDataCell>Cell</CTableDataCell>
    </CTableRow>
    <CTableRow theme="secondary">
      <CTableHeaderCell scope="row">Secondary</CTableHeaderCell>
      <CTableDataCell>Cell</CTableDataCell>
      <CTableDataCell>Cell</CTableDataCell>
    </CTableRow>
    <CTableRow theme="success">
      <CTableHeaderCell scope="row">Success</CTableHeaderCell>
      <CTableDataCell>Cell</CTableDataCell>
      <CTableDataCell>Cell</CTableDataCell>
    </CTableRow>
    <CTableRow theme="danger">
      <CTableHeaderCell scope="row">Danger</CTableHeaderCell>
      <CTableDataCell>Cell</CTableDataCell>
      <CTableDataCell>Cell</CTableDataCell>
    </CTableRow>
    <CTableRow theme="warning">
      <CTableHeaderCell scope="row">Warning</CTableHeaderCell>
      <CTableDataCell>Cell</CTableDataCell>
      <CTableDataCell>Cell</CTableDataCell>
    </CTableRow>
    <CTableRow theme="info">
      <CTableHeaderCell scope="row">Info</CTableHeaderCell>
      <CTableDataCell>Cell</CTableDataCell>
      <CTableDataCell>Cell</CTableDataCell>
    </CTableRow>
    <CTableRow theme="secondary">
      <CTableHeaderCell scope="row">Light</CTableHeaderCell>
      <CTableDataCell>Cell</CTableDataCell>
      <CTableDataCell>Cell</CTableDataCell>
    </CTableRow>
    <CTableRow theme="inverse">
      <CTableHeaderCell scope="row">Dark</CTableHeaderCell>
      <CTableDataCell>Cell</CTableDataCell>
      <CTableDataCell>Cell</CTableDataCell>
    </CTableRow>
  </CTableBody>
</CTable>

Since version 4.3.0 also this way.

const columns = [
  { key: 'class', _props: { scope: 'col' } },
  { key: 'heading_1', label: 'Heading', _props: { scope: 'col' } },
  { key: 'heading_2', label: 'Heading', _props: { scope: 'col' } },
]
const items = [
  {
    class: 'Default',
    heading_1: 'Cell',
    heading_2: 'Cell',
    _cellProps: { class: { scope: 'row' } },
  },
  {
    class: 'Primary',
    heading_1: 'Cell',
    heading_2: 'Cell',
    _cellProps: { class: { scope: 'row' } },
    _props: { theme: 'primary' },
  },
  {
    class: 'Secondary',
    heading_1: 'Cell',
    heading_2: 'Cell',
    _cellProps: { class: { scope: 'row' } },
    _props: { theme: 'secondary' },
  },
  {
    class: 'Success',
    heading_1: 'Cell',
    heading_2: 'Cell',
    _cellProps: { class: { scope: 'row' } },
    _props: { theme: 'success' },
  },
  {
    class: 'Danger',
    heading_1: 'Cell',
    heading_2: 'Cell',
    _cellProps: { class: { scope: 'row' } },
    _props: { theme: 'danger' },
  },
  {
    class: 'Warning',
    heading_1: 'Cell',
    heading_2: 'Cell',
    _cellProps: { class: { scope: 'row' } },
    _props: { theme: 'warning' },
  },
  {
    class: 'Info',
    heading_1: 'Cell',
    heading_2: 'Cell',
    _cellProps: { class: { scope: 'row' } },
    _props: { theme: 'info' },
  },
  {
    class: 'Light',
    heading_1: 'Cell',
    heading_2: 'Cell',
    _cellProps: { class: { scope: 'row' } },
    _props: { theme: 'light' },
  },
  {
    class: 'Dark',
    heading_1: 'Cell',
    heading_2: 'Cell',
    _cellProps: { class: { scope: 'row' } },
    _props: { theme: 'dark' },
  },
]
return <CTable columns={columns} items={items} />

Accented tables

Striped rows

Use striped property to add zebra-striping to any React table row within the <CTableBody>.

<CTable striped>
  ...
</CTable>

Striped columns

Enable striped to alternate row background colors for better visual distinction.

<CTable stripedColumns>
  ...
</CTable>

These classes can also be added to React table variants:

<CTable theme="inverse" striped>
  ...
</CTable>
<CTable theme="inverse" stripedColumns>
  ...
</CTable>
<CTable theme="success" striped>
  ...
</CTable>
<CTable theme="success" stripedColumns>
  ...
</CTable>

Hoverable rows

Use the hover prop to highlight rows when hovered by the user.

<CTable hover>
  ...
</CTable>
<CTable theme="inverse" hover>
  ...
</CTable>

These hoverable rows can also be combined with the striped variant:

<CTable striped hover>
  ...
</CTable>

Active tables

Highlight a table row or cell by adding a active property.

As mentioned before since version 4.3.0 we have two ways to generate tables, also with custom properties for rows, and cells.

const columns = [
  {
    key: 'id',
    label: '#',
    _props: { scope: 'col' },
  },
  {
    key: 'class',
    _props: { scope: 'col' },
  },
  {
    key: 'heading_1',
    label: 'Heading',
    _props: { scope: 'col' },
  },
  {
    key: 'heading_2',
    label: 'Heading',
    _props: { scope: 'col' },
  },
]
const items = [
  {
    id: 1,
    class: 'Mark',
    heading_1: 'Otto',
    heading_2: '@mdo',
    _props: { active: true },
    _cellProps: { id: { scope: 'row' } },
  },
  {
    id: 2,
    class: 'Jacob',
    heading_1: 'Thornton',
    heading_2: '@fat',
    _cellProps: { id: { scope: 'row' } },
  },
  {
    id: 3,
    class: 'Larry the Bird',
    heading_2: '@twitter',
    _cellProps: { id: { scope: 'row' }, class: { active: true, colSpan: 2 } },
  },
]
return <CTable columns={columns} items={items} />
<CTable>
  <CTableHead>
    <CTableRow>
      <CTableHeaderCell scope="col">#</CTableHeaderCell>
      <CTableHeaderCell scope="col">Class</CTableHeaderCell>
      <CTableHeaderCell scope="col">Heading</CTableHeaderCell>
      <CTableHeaderCell scope="col">Heading</CTableHeaderCell>
    </CTableRow>
  </CTableHead>
  <CTableBody>
    <CTableRow active>
      <CTableHeaderCell scope="row">1</CTableHeaderCell>
      <CTableDataCell>Mark</CTableDataCell>
      <CTableDataCell>Otto</CTableDataCell>
      <CTableDataCell>@mdo</CTableDataCell>
    </CTableRow>
    <CTableRow>
      <CTableHeaderCell scope="row">2</CTableHeaderCell>
      <CTableDataCell>Jacob</CTableDataCell>
      <CTableDataCell>Thornton</CTableDataCell>
      <CTableDataCell>@fat</CTableDataCell>
    </CTableRow>
    <CTableRow>
      <CTableHeaderCell scope="row">3</CTableHeaderCell>
      <CTableDataCell colSpan={2} active>
        Larry the Bird
      </CTableDataCell>
      <CTableDataCell>@twitter</CTableDataCell>
    </CTableRow>
  </CTableBody>
</CTable>
const columns = [
  {
    key: 'id',
    label: '#',
    _props: { scope: 'col' },
  },
  {
    key: 'class',
    _props: { scope: 'col' },
  },
  {
    key: 'heading_1',
    label: 'Heading',
    _props: { scope: 'col' },
  },
  {
    key: 'heading_2',
    label: 'Heading',
    _props: { scope: 'col' },
  },
]
const items = [
  {
    id: 1,
    class: 'Mark',
    heading_1: 'Otto',
    heading_2: '@mdo',
    _props: { active: true },
    _cellProps: { id: { scope: 'row' } },
  },
  {
    id: 2,
    class: 'Jacob',
    heading_1: 'Thornton',
    heading_2: '@fat',
    _cellProps: { id: { scope: 'row' } },
  },
  {
    id: 3,
    class: 'Larry the Bird',
    heading_2: '@twitter',
    _cellProps: { id: { scope: 'row' }, class: { active: true, colSpan: 2 } },
  },
]
return <CTable theme="inverse" columns={columns} items={items} />

Table borders

Bordered tables

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

<CTable bordered>
  ...
</CTable>

Border color utilities can be added to change colors:

<CTable bordered borderColor="primary">
  ...
</CTable>

Tables without borders

Add borderless property for a React table without borders.

<CTable borderless>
  ...
</CTable>
<CTable theme="inverse" borderless>
  ...
</CTable>

Card-like tables

Need a bordered, rounded table without nesting it in a card? Wrap the table and clip the corners.

With utilities

Compose border, border radius, and overflow utilities. Drop the table’s bottom margin with .mb-0.

<div className="border rounded overflow-hidden">
  <CTable striped className="mb-0">
    ...
  </CTable>
</div>

With card

Add the card property for the card look in one step. The table gets the default border and corner radius of a card, and a .theme-* class on an ancestor colours the frame the way it colours a card. The cells are clipped, and the borders that would stack on the frame go: the last row’s bottom border and the outer borders of a bordered table. A caption at the bottom keeps the line above it.

<CTable card hover>
  ...
</CTable>

Combine it with responsive when the table can overflow; both land on the same wrapper.

<CTable card responsive striped>
  ...
</CTable>
Clipping

card clips everything at the rounded edge: a dropdown menu opened from a cell, the focus ring of a control in an edge cell, and columns wider than the frame. Render menus outside the table with the dropdown’s portal property, and add responsive when the table can be wider than its container.

Small tables

Add small property to make any <CTable> more compact by cutting all cell padding in half.

<CTable small>
  ...
</CTable>

Table group dividers

Add a thicker, darker border between table groups—<CTableHead>, <CTableBody>, and <CTableFoot>—with .table-group-divider. Customize the color by changing the border-top-color (which we don’t currently provide a utility class for at this time).

import {
  CTable,
  CTableBody,
  CTableDataCell,
  CTableHead,
  CTableHeaderCell,
  CTableRow,
} from '@coreui/react'

export const TableGroupDividerExample = () => (
  <CTable>
    <CTableHead>
      <CTableRow>
        <CTableHeaderCell scope="col">#</CTableHeaderCell>
        <CTableHeaderCell scope="col">First</CTableHeaderCell>
        <CTableHeaderCell scope="col">Last</CTableHeaderCell>
        <CTableHeaderCell scope="col">Handle</CTableHeaderCell>
      </CTableRow>
    </CTableHead>
    <CTableBody className="table-group-divider">
      <CTableRow>
        <CTableHeaderCell scope="row">1</CTableHeaderCell>
        <CTableDataCell>Mark</CTableDataCell>
        <CTableDataCell>Otto</CTableDataCell>
        <CTableDataCell>@mdo</CTableDataCell>
      </CTableRow>
      <CTableRow>
        <CTableHeaderCell scope="row">2</CTableHeaderCell>
        <CTableDataCell>Jacob</CTableDataCell>
        <CTableDataCell>Thornton</CTableDataCell>
        <CTableDataCell>@fat</CTableDataCell>
      </CTableRow>
      <CTableRow>
        <CTableHeaderCell scope="row">3</CTableHeaderCell>
        <CTableDataCell colSpan={2}>Larry the Bird</CTableDataCell>
        <CTableDataCell>@twitter</CTableDataCell>
      </CTableRow>
    </CTableBody>
  </CTable>
)
import {
  CTable,
  CTableBody,
  CTableDataCell,
  CTableHead,
  CTableHeaderCell,
  CTableRow,
} from '@coreui/react'

export const TableGroupDividerExample = () => (
  <CTable>
    <CTableHead>
      <CTableRow>
        <CTableHeaderCell scope="col">#</CTableHeaderCell>
        <CTableHeaderCell scope="col">First</CTableHeaderCell>
        <CTableHeaderCell scope="col">Last</CTableHeaderCell>
        <CTableHeaderCell scope="col">Handle</CTableHeaderCell>
      </CTableRow>
    </CTableHead>
    <CTableBody className="table-group-divider">
      <CTableRow>
        <CTableHeaderCell scope="row">1</CTableHeaderCell>
        <CTableDataCell>Mark</CTableDataCell>
        <CTableDataCell>Otto</CTableDataCell>
        <CTableDataCell>@mdo</CTableDataCell>
      </CTableRow>
      <CTableRow>
        <CTableHeaderCell scope="row">2</CTableHeaderCell>
        <CTableDataCell>Jacob</CTableDataCell>
        <CTableDataCell>Thornton</CTableDataCell>
        <CTableDataCell>@fat</CTableDataCell>
      </CTableRow>
      <CTableRow>
        <CTableHeaderCell scope="row">3</CTableHeaderCell>
        <CTableDataCell colSpan={2}>Larry the Bird</CTableDataCell>
        <CTableDataCell>@twitter</CTableDataCell>
      </CTableRow>
    </CTableBody>
  </CTable>
)

Vertical alignment

Table cells of <CTableHead> are always vertical aligned to the bottom. Table cells in <CTableBody> inherit their alignment from <CTable> and are aligned to the the top by default. Use the align property to re-align where needed.

In version 4.3.0 we introduced a new way to create a table, similarly to our Smart Table component.

const columns = [
  {
    key: 'heading_1',
    _props: { className: 'w-25', scope: 'col' },
  },
  {
    key: 'heading_2',
    _props: { className: 'w-25', scope: 'col' },
  },
  {
    key: 'heading_3',
    _props: { className: 'w-25', scope: 'col' },
  },
  {
    key: 'heading_4',
    _props: { className: 'w-25', scope: 'col' },
  },
]
const items = [
  {
    heading_1: <>This cell inherits <code>vertical-align: middle;</code> from the table</>,
    heading_2: <>This cell inherits <code>vertical-align: middle;</code> from the table</>,
    heading_3: <>This cell inherits <code>vertical-align: middle;</code> from the table</>,
    heading_4: 'This here is some placeholder text, intended to take up quite a bit of vertical space, to demonstrate how the vertical alignment works in the preceding cells.',
  },
  {
    heading_1: <>This cell inherits <code>vertical-align: bottom;</code> from the table row</>,
    heading_2: <>This cell inherits <code>vertical-align: bottom;</code> from the table row</>,
    heading_3: <>This cell inherits <code>vertical-align: bottom;</code> from the table row</>,
    heading_4: 'This here is some placeholder text, intended to take up quite a bit of vertical space, to demonstrate how the vertical alignment works in the preceding cells.',
    _props: { align: 'bottom' }
  },
  {
    heading_1: <>This cell inherits <code>vertical-align: middle;</code> from the table</>,
    heading_2: <>This cell inherits <code>vertical-align: middle;</code> from the table</>,
    heading_3: 'This cell is aligned to the top.',
    heading_4: 'This here is some placeholder text, intended to take up quite a bit of vertical space, to demonstrate how the vertical alignment works in the preceding cells.',
      _cellProps: { heading_3: { align: 'top' }},
  },
]
return <CTable align="middle" columns={columns} items={items} />

You can also put all table components together manually as hitherto.

<CTable align="middle" responsive>
  <CTableHead>
    <CTableRow>
      <CTableHeaderCell scope="col" className="w-25">
        Heading 1
      </CTableHeaderCell>
      <CTableHeaderCell scope="col" className="w-25">
        Heading 2
      </CTableHeaderCell>
      <CTableHeaderCell scope="col" className="w-25">
        Heading 3
      </CTableHeaderCell>
      <CTableHeaderCell scope="col" className="w-25">
        Heading 4
      </CTableHeaderCell>
    </CTableRow>
  </CTableHead>
  <CTableBody>
    <CTableRow>
      <CTableDataCell>
        This cell inherits <code>vertical-align: middle;</code> from the table
      </CTableDataCell>
      <CTableDataCell>
        This cell inherits <code>vertical-align: middle;</code> from the table
      </CTableDataCell>
      <CTableDataCell>
        This cell inherits <code>vertical-align: middle;</code> from the table
      </CTableDataCell>
      <CTableDataCell>
        This here is some placeholder text, intended to take up quite a bit of vertical space, to
        demonstrate how the vertical alignment works in the preceding cells.
      </CTableDataCell>
    </CTableRow>
    <CTableRow align="bottom">
      <CTableDataCell>
        This cell inherits <code>vertical-align: bottom;</code> from the table row
      </CTableDataCell>
      <CTableDataCell>
        This cell inherits <code>vertical-align: bottom;</code> from the table row
      </CTableDataCell>
      <CTableDataCell>
        This cell inherits <code>vertical-align: bottom;</code> from the table row
      </CTableDataCell>
      <CTableDataCell>
        This here is some placeholder text, intended to take up quite a bit of vertical space, to
        demonstrate how the vertical alignment works in the preceding cells.
      </CTableDataCell>
    </CTableRow>
    <CTableRow>
      <CTableDataCell>
        This cell inherits <code>vertical-align: middle;</code> from the table
      </CTableDataCell>
      <CTableDataCell>
        This cell inherits <code>vertical-align: middle;</code> from the table
      </CTableDataCell>
      <CTableDataCell align="top">This cell is aligned to the top.</CTableDataCell>
      <CTableDataCell>
        This here is some placeholder text, intended to take up quite a bit of vertical space, to
        demonstrate how the vertical alignment works in the preceding cells.
      </CTableDataCell>
    </CTableRow>
  </CTableBody>
</CTable>

Nesting

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

<CTable striped>
  <CTableHead>
    <CTableRow>
      <CTableHeaderCell scope="col">#</CTableHeaderCell>
      <CTableHeaderCell scope="col">Class</CTableHeaderCell>
      <CTableHeaderCell scope="col">Heading</CTableHeaderCell>
      <CTableHeaderCell scope="col">Heading</CTableHeaderCell>
    </CTableRow>
  </CTableHead>
  <CTableBody>
    <CTableRow>
      <CTableHeaderCell scope="row">1</CTableHeaderCell>
      <CTableDataCell>Mark</CTableDataCell>
      <CTableDataCell>Otto</CTableDataCell>
      <CTableDataCell>@mdo</CTableDataCell>
    </CTableRow>
    <CTableRow>
      <CTableHeaderCell colSpan={4}>
        <CTable>
          <CTableHead>
            <CTableRow>
              <CTableHeaderCell scope="col">Header</CTableHeaderCell>
              <CTableHeaderCell scope="col">Header</CTableHeaderCell>
              <CTableHeaderCell scope="col">Header</CTableHeaderCell>
            </CTableRow>
          </CTableHead>
          <CTableBody>
            <CTableRow>
              <CTableHeaderCell scope="row">A</CTableHeaderCell>
              <CTableDataCell>First</CTableDataCell>
              <CTableDataCell>Last</CTableDataCell>
            </CTableRow>
            <CTableRow>
              <CTableHeaderCell scope="row">B</CTableHeaderCell>
              <CTableDataCell>First</CTableDataCell>
              <CTableDataCell>Last</CTableDataCell>
            </CTableRow>
            <CTableRow>
              <CTableHeaderCell scope="row">C</CTableHeaderCell>
              <CTableDataCell>First</CTableDataCell>
              <CTableDataCell>Last</CTableDataCell>
            </CTableRow>
          </CTableBody>
        </CTable>
      </CTableHeaderCell>
    </CTableRow>
    <CTableRow>
      <CTableHeaderCell scope="row">3</CTableHeaderCell>
      <CTableDataCell colSpan={2}>Larry the Bird</CTableDataCell>
      <CTableDataCell>@twitter</CTableDataCell>
    </CTableRow>
  </CTableBody>
</CTable>

Anatomy

Table head

Similar to tables and dark tables, use the modifier prop color="secondary" or color="inverse" to make <CTableHead>s appear light or dark gray.

<CTable>
  <CTableHead theme="secondary">
    ...
  </CTableHead>
  <CTableBody>
    ...
  </CTableBody>
</CTable>

If you generate a table using the new method incorporated in version 4.3.0, you have to use tableHeadProps property to pass properties to the table header component.

const columns = [...]
const items = [...]

return <CTable columns={columns} items={items} tableHeadProps={{ color: 'light' }} />
<CTable>
  <CTableHead theme="inverse">
    ...
  </CTableHead>
  <CTableBody>
    ...
  </CTableBody>
</CTable>

Starting from version 4.3.0 also this way.

const columns = [...]
const items = [...]

return <CTable columns={columns} items={items} tableHeadProps={{ color: 'dark' }} />

Table foot

<CTable>
  <CTableHead theme="secondary">
    ...
  </CTableHead>
  <CTableBody>
    ...
  <CTableHead>
    <CTableRow>
      <CTableDataCell>Footer</CTableDataCell>
      <CTableDataCell>Footer</CTableDataCell>
      <CTableDataCell>Footer</CTableDataCell>
      <CTableDataCell>Footer</CTableDataCell>
    </CTableRow>
  </CTableHead>
</CTable>

Starting from version 4.3.0 also this way.

const columns = [...]
const footer = [
  'Footer',
  'Footer',
  'Footer',
  'Footer',
]
const items = [...]

return <CTable columns={columns} footer={footer} items={items} tableHeadProps={{ color: 'light' }}/>

Captions

A <CTableCaption> 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.

<CTable>
  <CTableCaption>List of users</CTableCaption>
  <CTableHead>
    ...
  </CTableHead>
  <CTableBody>
    ...
  </CTableBody>
</CTable>

Starting from version 4.3.0 also this way.

const columns = [...]
const items = [...]

return <CTable caption="List of users" columns={columns} items={items} />

Add captionTop to put the caption on the top of the table.

<CTable captionTop>
  <CTableCaption>List of users</CTableCaption>
  <CTableHead>
    ...
  </CTableHead>
  <CTableBody>
    ...
  </CTableBody>
</CTable>

It combines with the caption property the same way.

const columns = [...]
const items = [...]

return <CTable caption="List of users" captionTop columns={columns} items={items} />

Responsive tables

Responsive tables allow tables to be scrolled horizontally with ease. Make any table responsive across all viewports by adding a responsive property. Or, pick a maximum breakpoint with which to have a responsive table up to by using responsive="{-sm|-md|-lg|-xl|-2xl}".

<CTable responsive>
  ...
</CTable>
<CTable responsive="sm">
  ...
</CTable>
<CTable responsive="md">
  ...
</CTable>
<CTable responsive="lg">
  ...
</CTable>
<CTable responsive="xl">
  ...
</CTable>
<CTable responsive="2xl">
  ...
</CTable>

Stacked tables

A table that scrolls sideways is still a table; on a narrow screen it is often easier to read one record at a time. Add .table-stacked{-sm|-md|-lg|-xl|-2xl} to <CTable> to turn each row into a block below that breakpoint — the header is hidden from sight (it stays in the accessibility tree) and every cell carries its own label.

Two things are required: the responsive property, because that wrapper is the query container the class measures, and a data-cell attribute on every cell after the first, which supplies the label the hidden header would have given. The first cell is treated as the record’s title and needs no label.

import {
  CTable,
  CTableBody,
  CTableDataCell,
  CTableHead,
  CTableHeaderCell,
  CTableRow,
} from '@coreui/react'

export const TableStackedExample = () => (
  <CTable className="table-stacked-md" responsive>
    <CTableHead>
      <CTableRow>
        <CTableHeaderCell scope="col">Name</CTableHeaderCell>
        <CTableHeaderCell scope="col">Role</CTableHeaderCell>
        <CTableHeaderCell scope="col">Email</CTableHeaderCell>
      </CTableRow>
    </CTableHead>
    <CTableBody>
      <CTableRow>
        <CTableDataCell>Mark Otto</CTableDataCell>
        <CTableDataCell data-cell="Role">Maintainer</CTableDataCell>
        <CTableDataCell data-cell="Email">[email protected]</CTableDataCell>
      </CTableRow>
      <CTableRow>
        <CTableDataCell>Jacob Thornton</CTableDataCell>
        <CTableDataCell data-cell="Role">Designer</CTableDataCell>
        <CTableDataCell data-cell="Email">[email protected]</CTableDataCell>
      </CTableRow>
    </CTableBody>
  </CTable>
)
import {
  CTable,
  CTableBody,
  CTableDataCell,
  CTableHead,
  CTableHeaderCell,
  CTableRow,
} from '@coreui/react'

export const TableStackedExample = () => (
  <CTable className="table-stacked-md" responsive>
    <CTableHead>
      <CTableRow>
        <CTableHeaderCell scope="col">Name</CTableHeaderCell>
        <CTableHeaderCell scope="col">Role</CTableHeaderCell>
        <CTableHeaderCell scope="col">Email</CTableHeaderCell>
      </CTableRow>
    </CTableHead>
    <CTableBody>
      <CTableRow>
        <CTableDataCell>Mark Otto</CTableDataCell>
        <CTableDataCell data-cell="Role">Maintainer</CTableDataCell>
        <CTableDataCell data-cell="Email">[email protected]</CTableDataCell>
      </CTableRow>
      <CTableRow>
        <CTableDataCell>Jacob Thornton</CTableDataCell>
        <CTableDataCell data-cell="Role">Designer</CTableDataCell>
        <CTableDataCell data-cell="Email">[email protected]</CTableDataCell>
      </CTableRow>
    </CTableBody>
  </CTable>
)

Because the breakpoint is read from the responsive wrapper rather than the window, a stacked table inside a narrow column stacks there while the same markup in the main content area stays a table.

API

Explore all available props and component options in the API reference below.