Skip to main content Skip to docs navigation

Flexible table styles with opt-in classes for responsive, accessible, and customizable data presentation in Chassis CSS.

Overview

Tables in Chassis CSS use an opt-in approach with the .table base class. This design choice respects the widespread use of native <table> elements in third-party plugins like calendars and datepickers. Add the base class to any <table>, then enhance with modifiers for borders, striping, hover states, and context variations. Table styles aren't inherited by nested tables, allowing for independent styling within complex layouts.

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">First</th>
      <th scope="col">Last</th>
      <th scope="col">Handle</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">1</th>
      <td>Mark</td>
      <td>Otto</td>
      <td>@mdo</td>
    </tr>
    <tr>
      <th scope="row">2</th>
      <td>Jacob</td>
      <td>Thornton</td>
      <td>@fat</td>
    </tr>
    <tr>
      <th scope="row">3</th>
      <td>John</td>
      <td>Doe</td>
      <td>@social</td>
    </tr>
  </tbody>
</table>

Accented tables

Enhance your tables with visual accents to improve readability and create visual hierarchy. These options help users scan and interpret tabular data more effectively.

Striped rows

Add .striped to create alternating background colors for rows within the <tbody>, making it easier to scan across wide tables.

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table striped">
  ...
</table>

Striped columns

Use .striped-columns to apply zebra-striping to columns instead of rows, which can be useful for data-dense tables where vertical scanning is important.

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table striped-columns">
  ...
</table>

Hoverable rows

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

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table hoverable striped">
  ...
</table>

Active tables

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

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table hoverable striped">
  <thead>
    ...
  </thead>
  <tbody>
    <tr class="active">
      ...
    </tr>
    <tr>
      <th scope="row">2</th>
      <td>Jacob</td>
      <td class="active">Thornton</td>
      <td>@fat</td>
    </tr>
    <tr>
      ...
    </tr>
  </tbody>
</table>

Table borders

Control the visual boundaries of your tables using border modifiers. These classes help define table structure and separate content areas to improve readability and organization.

Bordered tables

Add .bordered to apply distinct borders to the entire table, including cell boundaries, creating clear visual separation between data points.

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table bordered">
  ...
</table>

Border color utilities can be added to change colors:

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table bordered border-primary">
  ...
</table>

Borderless tables

Apply .borderless to remove all borders from your table for a cleaner, more minimalist appearance.

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table borderless">
  ...
</table>

Border Radius

Customize the corners of bordered tables using CSS variables to override the default border-radius design tokens.

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table bordered" style="--cx-border-radius: 0">
  ...
</table>

Or use it in a wrapper with table scoping.

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table bordered">
  <thead>
    ...
  </thead>
  <tbody>
    ...
  </tbody>
</table>
<div style="--cx-table-border-radius: 1rem">
  <table class="table bordered">
    ...
  </table>
</div>

Border radius overriding needs $enable-table-border-radius to be set to true in _settings.scss.

Context Variants

CSS Only

Use .context with a color name (like .primary) to apply a specific color scheme to your table. You can further customize the appearance using style modifiers like .solid or .smooth.

Context Colors

Add .context followed by a color name (e.g., .context.primary, .context.success) to apply that color scheme to tables, rows, or individual cells.

Class Heading Heading
Base Cell Cell
Default Cell Cell
Alternate Cell Cell
Primary Cell Cell
Secondary Cell Cell
Neutral Cell Cell
Danger Cell Cell
Success Cell Cell
Warning Cell Cell
Info Cell Cell
Black Cell Cell
White Cell Cell
<!-- On tables -->
<table class="table context default">...</table>
<table class="table context alternate">...</table>
<table class="table context primary">...</table>
<table class="table context secondary">...</table>
<table class="table context neutral">...</table>
<table class="table context danger">...</table>
<table class="table context success">...</table>
<table class="table context warning">...</table>
<table class="table context info">...</table>
<table class="table context black">...</table>
<table class="table context white">...</table>

<!-- On heads -->
<thead class="context primary">
  ...
</thead>

<!-- On bodies -->
<tbody class="context primary">
  ...
</tbody>

<!-- On rows -->
<tr class="context primary">
  ...
</tr>

<!-- On cells (`td` or `th`) -->
<td class="context primary">
  ...
</td>

Accessibility tip: Color alone shouldn't convey meaning as it's not perceived by assistive technology users. Ensure clarity through text with adequate contrast, ARIA attributes where needed, and consider using .visually-hidden for screen reader content.

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table striped hoverable context primary">
...
</table>

Context styles

Add .solid or .smooth alongside .context and a color to modify how the context color appears. The .solid style creates a more prominent color effect, while .smooth provides a softer appearance.

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table context primary solid">
  ...
</table>
# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table context primary smooth">
  ...
</table>

Color Modes

Apply different color themes to tables using the data-cx-theme attribute. This allows you to maintain visual consistency with dark or light themed interfaces regardless of the global theme setting.

Add data-cx-theme="light" or data-cx-theme="dark" to any table element:

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table" data-cx-theme="dark">
  ...
</table>

Context variants work seamlessly with explicit theme settings:

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table context primary" data-cx-theme="dark">
  ...
</table>

Table Sizing

Customize table dimensions and text sizes using CSS variables to override design tokens, giving you fine-grained control over your table's appearance.

Basic sizing

Adjust cell padding and font sizes directly on the table:

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table" style="--cx-td-font-size: 1rem; --cx-cell-padding-y: 1rem">
  ...
</table>

Targeted elements

Target specific table components by setting styles for <thead> & <tbody> elements or use a wrapper with scoping:

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<div style="--cx-table-cell-padding-y: 1rem; --cx-table-th-font-size: 1rem;">
  <table class="table">
    <thead style="--cx-cell-padding-y: .25rem">
      ...
    </thead>
    <tbody style="--cx-td-font-size: 1rem">
      ...
    </tbody>
  </table>
</div>

Nesting

Border styles and context variants are not inherited by nested tables.

Column 1Column 2Column 3
FirstSecondThird
# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
FirstSecondThird
<table class="table striped bordered">
  ...
  <tr>
    <td colspan="3" class="p-medium">
      <table class="table mb-0">
        ...
      </table>
    </td>
  </tr>
  ...
</table>

Inherit context

Apply the context class without a variant to enable the nested table to inherit the parent table's context.

Column 1Column 2Column 3
FirstSecondThird
# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
FirstSecondThird
<table class="table striped bordered context primary">
  ...
  <tr>
    <td colspan="3" class="p-medium">
      <table class="table context mb-0">
        ...
      </table>
    </td>
  </tr>
  ...
</table>

Anatomy

Customize the structural elements of tables to create effective hierarchies and improve both visual presentation and accessibility.

Table head

Add emphasis and visual hierarchy using custom styling for the <thead> element. Apply context classes to <thead> or utility classes to <tr> elements for custom appearances.

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table">
  <thead class="context alternate">
    ...
  </thead>
  <tbody>
    ...
  </tbody>
</table>
# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table">
  <thead>
    <tr class="bg-main fg-primary">
      ...
    </tr>
  </thead>
  <tbody>
    ...
  </tbody>
</table>

Table foot

Include a <tfoot> element to display summary information, totals, or notes at the bottom of the table. Apply context classes to <tfoot> or utility classes to <tr> elements for custom appearances.

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
Footer 1 Footer 2 Footer 3 Footer 4
<table class="table">
  <thead>
    ...
  </thead>
  <tbody>
    ...
  </tbody>
  <tfoot class="context neutral">
    ...
  </tfoot>
</table>

Captions

Improve accessibility and provide context by including a <caption> that briefly describes the table's content and purpose. Screen readers announce captions first, helping users decide if they want to explore the table.

List of users
# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table">
  <caption>List of users</caption>
  ...
</table>

You can also position the caption at the top of the table with .caption-top for greater visibility.

List of users
# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
<table class="table caption-top">
  <caption>List of users</caption>
  ...
</table>

Group dividers

Create visual separation between table sections with enhanced borders using the .table-divider class.

# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
Footer 1 Footer 2 Footer 3 Footer 4
<table class="table">
  <thead>
    ...
  </thead>
  <tbody class="table-divider">
    ...
  </tbody>
  <tfoot class="table-divider">
    ...
  </tfoot>
</table>
# First Last Handle
1 Mark Otto @mdo
2 Jacob Thornton @fat
3 John Doe @social
Footer 1 Footer 2 Footer 3 Footer 4
<table class="table context primary">
  <thead>
    ...
  </thead>
  <tbody class="table-divider">
    ...
  </tbody>
  <tfoot class="table-divider">
    ...
  </tfoot>
</table>

Vertical alignment

Control the vertical positioning of content within table cells to handle varying content lengths and improve visual harmony. By default, <thead> cells align content to the bottom, while <tbody> cells inherit alignment from the table (defaulting to top alignment).

Use the vertical align utility classes (.align-top, .align-middle, or .align-bottom) on tables, rows, or individual cells to customize alignment:

Column 1Column 2Column 3Column 4
This cell inherits vertical-align: middle; from the tableThis cell inherits vertical-align: middle; from the tableThis cell inherits vertical-align: middle; from the tableThis here is some long text, intended to take up quite a bit of vertical space, to demonstrate how the vertical alignment works in the preceding cells.
This cell inherits vertical-align: bottom; from the table rowThis cell inherits vertical-align: bottom; from the table rowThis cell inherits vertical-align: bottom; from the table rowThis here is some long text, intended to take up quite a bit of vertical space, to demonstrate how the vertical alignment works in the preceding cells.
This cell inherits vertical-align: middle; from the tableThis cell aligned to the top.This cell is aligned to the bottom.This here is some long text, intended to take up quite a bit of vertical space, to demonstrate how the vertical alignment works in the preceding cells.
<div class="table-responsive">
  <table class="table align-middle">
    <thead>
      <tr>
        ...
      </tr>
    </thead>
    <tbody>
      <tr>
        ...
      </tr>
      <tr class="align-bottom">
        ...
      </tr>
      <tr>
        <td>...</td>
        <td class="align-top">This cell is aligned to the top.</td>
        <td class="align-bottom">This cell is aligned to the bottom.</td>
        <td>...</td>
      </tr>
    </tbody>
  </table>
</div>

Responsive tables

Responsive tables allow tables to be scrolled horizontally with ease. Make any table responsive across all viewports by wrapping a .table with .table-responsive. Or, pick a maximum breakpoint with which to have a responsive table up to by using .table-responsive{-small|-medium|-large|-xlarge|-2xlarge}.

Vertical clipping/truncation

Responsive tables make use of overflow-y: hidden, which clips off any content that goes beyond the bottom or top edges of the table. In particular, this can clip off dropdown menus and other third-party widgets.

Always responsive

Across every breakpoint, use .table-responsive for horizontally scrolling tables.

#HeadingHeadingHeadingHeadingHeadingHeadingHeadingHeading
1CellCellCellCellCellCellCellCell
2CellCellCellCellCellCellCellCell
3CellCellCellCellCellCellCellCell
<div class="table-responsive">
  <table class="table">
    ...
  </table>
</div>

Breakpoint specific

Use .{breakpoint}:table-responsive as needed to create responsive tables up to a particular breakpoint. From that breakpoint and up, the table will behave normally and not scroll horizontally.

These tables may appear broken until their responsive styles apply at specific viewport widths.

#HeadingHeadingHeadingHeadingHeadingHeadingHeadingHeading
1CellCellCellCellCellCellCellCell
2CellCellCellCellCellCellCellCell
3CellCellCellCellCellCellCellCell
#HeadingHeadingHeadingHeadingHeadingHeadingHeadingHeading
1CellCellCellCellCellCellCellCell
2CellCellCellCellCellCellCellCell
3CellCellCellCellCellCellCellCell
#HeadingHeadingHeadingHeadingHeadingHeadingHeadingHeading
1CellCellCellCellCellCellCellCell
2CellCellCellCellCellCellCellCell
3CellCellCellCellCellCellCellCell
#HeadingHeadingHeadingHeadingHeadingHeadingHeadingHeading
1CellCellCellCellCellCellCellCell
2CellCellCellCellCellCellCellCell
3CellCellCellCellCellCellCellCell
#HeadingHeadingHeadingHeadingHeadingHeadingHeadingHeading
1CellCellCellCellCellCellCellCell
2CellCellCellCellCellCellCellCell
3CellCellCellCellCellCellCellCell
#HeadingHeadingHeadingHeadingHeadingHeadingHeadingHeading
1CellCellCellCellCellCellCellCell
2CellCellCellCellCellCellCellCell
3CellCellCellCellCellCellCellCell
<div class="table-responsive">
  <table class="table">
    ...
  </table>
</div>

<div class="small:table-responsive">
  <table class="table">
    ...
  </table>
</div>

<div class="medium:table-responsive">
  <table class="table">
    ...
  </table>
</div>

<div class="large:table-responsive">
  <table class="table">
    ...
  </table>
</div>

<div class="xlarge:table-responsive">
  <table class="table">
    ...
  </table>
</div>

<div class="2xlarge:table-responsive">
  <table class="table">
    ...
  </table>
</div>

CSS

This component can be customized using CSS variables, allowing for styles to be modified dynamically on the page. These CSS variables are part of Chassis CSS's design token system, giving design teams control over component appearance. See the design tokens page for more details.

Custom properties

These CSS variables control the component's appearance and can be modified dynamically on the page. Components use cascading variables, allowing seamless variations in size, color, and style without redundant style declarations through component inheritance and the context class system.

--#{$prefix}fg-color: var(--#{$prefix}table-td-fg-color, #{$table-td-fg-color});
--#{$prefix}bg-color: var(--#{$prefix}table-td-bg-color, #{$table-td-bg-color});
--#{$prefix}th-fg-color: var(--#{$prefix}table-th-fg-color, #{$table-th-fg-color});
--#{$prefix}th-bg-color: var(--#{$prefix}table-th-bg-color, #{$table-th-bg-color});
--#{$prefix}striped-fg-color: var(--#{$prefix}table-striped-fg-color, #{$table-striped-fg-color});
--#{$prefix}striped-bg-color: var(--#{$prefix}table-striped-bg-color, #{$table-striped-bg-color});
--#{$prefix}hover-fg-color: var(--#{$prefix}table-hover-fg-color, #{$table-hover-fg-color});
--#{$prefix}hover-bg-color: var(--#{$prefix}table-hover-bg-color, #{$table-hover-bg-color});
--#{$prefix}active-fg-color: var(--#{$prefix}table-active-fg-color, #{$table-active-fg-color});
--#{$prefix}active-bg-color: var(--#{$prefix}table-active-bg-color, #{$table-active-bg-color});
--#{$prefix}border-color: var(--#{$prefix}table-border-color, #{$table-border-color});
--#{$prefix}cue-color: var(--#{$prefix}table-cue-color, #{$table-cue-color});

--#{$prefix}cell-padding-y: var(--#{$prefix}table-cell-padding-y, #{$table-cell-padding-y});
--#{$prefix}cell-padding-x: var(--#{$prefix}table-cell-padding-x, #{$table-cell-padding-x});

@if $enable-table-font-tokens {
  @include map-font($table-td-font, table, td); // e.g. --#{$prefix}td-[property-name]: var(--#{$prefix}table-td-[propery-name], [value]);
  @include map-font($table-th-font, table, th); // e.g. --#{$prefix}th-[property-name]: var(--#{$prefix}table-th-[propery-name], [value]);
}
@if $enable-table-border-radius {
  --#{$prefix}border-radius: var(--#{$prefix}table-border-radius, #{$table-border-radius});
  @include border-radius(var(--#{$prefix}border-radius));
}

Sass variables

These Sass variables are also exposed as CSS custom properties using the --cx- prefix. A Sass variable $variable-name becomes available as --cx-variable-name in CSS, allowing for styles to be modified dynamically on the page. See the context components page for more details.

// CSS custom properties
$table-divider-color:               currentcolor;
$table-cell-vertical-align:         top;
// Sass-only variables
$table-th-font-weight:              700;
$table-striped-order:               even;
$table-striped-columns-order:       even;
$table-caption-color:               var(--#{$prefix}fg-subtle);
$table-td-fg-context:               var(--#{$prefix}fg-main);
$table-td-bg-context:               var(--#{$prefix}bg-main);
$table-th-fg-context:               var(--#{$prefix}fg-main);
$table-th-bg-context:               var(--#{$prefix}bg-evident);
$table-striped-fg-context:          var(--#{$prefix}fg-main);
$table-striped-bg-context:          var(--#{$prefix}bg-even);
$table-hover-fg-context:            var(--#{$prefix}fg-main);
$table-hover-bg-context:            var(--#{$prefix}dim-slight);
$table-active-fg-context:           var(--#{$prefix}fg-highlight);
$table-active-bg-context:           var(--#{$prefix}bg-highlight);
$table-border-context:              var(--#{$prefix}border-subtle);
$table-cue-context:                 var(--#{$prefix}cue-main);

Design tokens

These design tokens with $cx prefixes are managed by design teams in Figma using the Tokens Studio plugin. See the design tokens page for more details.

$table-td-fg-color:               $cx-color-table-fg-data;
$table-td-bg-color:               $cx-color-table-bg-data;
$table-th-fg-color:               $cx-color-table-fg-head;
$table-th-bg-color:               $cx-color-table-bg-head;
$table-striped-fg-color:          $cx-color-table-fg-data;
$table-striped-bg-color:          $cx-color-table-bg-alt;
$table-active-fg-color:           $cx-color-table-fg-data;
$table-active-bg-color:           $cx-color-table-bg-active;
$table-hover-fg-color:            $cx-color-table-fg-data;
$table-hover-bg-color:            $cx-color-table-bg-hover;
$table-cue-color:                 $cx-color-table-cue-active;
$table-border-color:              $cx-color-table-border-main;

$table-cell-padding-y:            $cx-space-table-cell-padding-y;
$table-cell-padding-x:            $cx-space-table-cell-padding-x;
$table-border-width:              $cx-border-width-table-main;
$table-border-radius:             $cx-border-radius-table-main;
$table-active-indicator-size:     $cx-size-asset-indicator;
$table-th-font:                   $cx-font-table-head-text;
$table-td-font:                   $cx-font-table-data-text;