Skip to content

Table

A styled <table>. Write the <thead> and <tbody> yourself; the component sets the classes and the scroll wrapper.

striped adds zebra rows, hover highlights the row under the pointer, bordered draws a border around every cell. Combine them freely:

size="sm" tightens the cell padding, borderless removes the borders, and nowrap keeps the cell text on one line. transparent removes the background of the header cells, and center centers the cells horizontally:

vcenter centers the cells vertically, for rows with avatars or buttons:

mobile stacks each row into a block below a breakpoint (table-mobile-{breakpoint}): sm, md, lg, xl or xxl. The header row is hidden, and each cell is labelled by its data-label attribute: write the cells with Table:Cell and its label prop. Narrow the window to see it:

Table:Cell with truncate cuts a long text with an ellipsis instead of stretching the table: the cell takes the remaining width (td-truncate) and wraps its content in a <div class="text-truncate">. Here nowrap keeps the other cells on one line:

Table:Sort renders a header button with a sort arrow (table-sort), to put in a <th>. field is rendered as data-sort, and direction (asc or desc) marks the current sort. The classes only style the header: sort the rows yourself, e.g. with List.js, which reads data-sort, or with a link that reloads the page sorted.

selectable highlights the rows whose Table:Check is checked (table-selectable), with CSS only. Table:Check renders the row checkbox; give each one an aria-label naming its row. A “select all” checkbox in the header needs your own JavaScript:

card runs the table edge to edge in a card, aligned with the card padding and without a bottom margin (card-table). Classes and other attributes go to the <table>, not to the wrapper:

The table is wrapped in a <div class="table-responsive"> by default. Pass responsive="{{ false }}" to render the bare <table> (see boolean props):

Prop Type Default Description
responsive bool true Wraps the table in <div class="table-responsive">
vcenter bool false Centers cells vertically (table-vcenter)
center bool false Centers cells horizontally (table-center)
striped bool false Zebra rows (table-striped)
hover bool false Highlights the hovered row (table-hover)
bordered bool false Borders on every cell (table-bordered)
borderless bool false No borders (table-borderless)
transparent bool false No background on the header cells (table-transparent)
nowrap bool false Cell text does not wrap (table-nowrap)
selectable bool false Highlights the rows whose Table:Check is checked (table-selectable)
size string 'md' sm md: sm tightens the cell padding (table-sm)
mobile string? null sm md lg xl xxl: stacks the rows below this breakpoint (table-mobile-*)
card bool false Edge to edge inside a card, no bottom margin (card-table)

Other attributes go to the <table>.

Table:Sort:

Prop Type Default Description
field string? null Sort key, rendered as data-sort
direction string? null asc desc: marks the current sort direction

Other attributes go to the <button class="table-sort">.

Table:Cell:

Prop Type Default Description
label string? null Column name shown when mobile stacks the row (data-label)
truncate bool false Cuts the content with an ellipsis (td-truncate, content in a .text-truncate div)

Other attributes go to the <td>. Table:Check has no props: its attributes (name, value, checked, aria-label…) go to the <input type="checkbox">.

Component Renders
Table:Sort <button type="button" class="table-sort">: a sortable header
Table:Check <input type="checkbox" class="form-check-input table-selectable-check">: a row checkbox
Table:Cell <td>: a cell with a mobile label or a truncated content
Block Default
content Empty: the children, the <thead> and <tbody>, go here

Table:Sort and Table:Cell have an empty content block too, for the header label and the cell content.