CSS-Only

Table

Accessible table component with striping, hover, borders, sizes, sticky headers, and responsive card layouts. Works by default, enhances with data attributes.

Example

Name Email Role Status
Alice Johnson alice@example.com Admin Active
Bob Smith bob@example.com User Active
Carol White carol@example.com Editor Pending
<table class="omni-table">
  <thead>
    <tr>
      <th>Name</th>
      <th>Email</th>
      <th>Role</th>
      <th>Status</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Alice Johnson</td>
      <td>alice@example.com</td>
      <td>Admin</td>
      <td>Active</td>
    </tr>
  </tbody>
</table>

Variants

Striped Rows

Use data-striped="true" for alternating row backgrounds:

Product Price Quantity Total
Widget A $19.99 5 $99.95
Widget B $29.99 3 $89.97
Widget C $39.99 2 $79.98
<table class="omni-table" data-striped="true">
  <!-- ... -->
</table>

Hoverable Rows

Use data-hover="true" to highlight rows on hover:

Name Department Location
Alice Johnson Engineering San Francisco
Bob Smith Marketing New York
Carol White Sales Chicago

Bordered

Use data-bordered="true" for full cell borders:

ID Task Status
001 Design mockups Done
002 Implement feature In Progress

Borderless

Use data-borderless="true" to remove all borders:

Metric Value Change
Revenue $1,234,567 +12%
Users 45,678 +8%

Sizes

Use data-size to adjust cell padding and font size:

Small

Name Email Status
Alice alice@example.com Active
Bob bob@example.com Active

Dense

For data-heavy displays with minimal spacing:

Code Description Qty Price
A001 Widget 5 $19.99
A002 Gadget 3 $29.99
A003 Doohickey 7 $9.99

Large

Feature Description
Tables Display tabular data accessibly
Responsive Works on mobile with card layout

With Footer

Use <tfoot> for summary rows or totals:

Item Quantity Price Total
Widget A 5 $19.99 $99.95
Widget B 3 $29.99 $89.97
Widget C 2 $39.99 $79.98
Grand Total $269.90
<table class="omni-table">
  <thead>...</thead>
  <tbody>...</tbody>
  <tfoot>
    <tr>
      <th colspan="3">Grand Total</th>
      <td>$269.90</td>
    </tr>
  </tfoot>
</table>

Sticky Header

Use data-sticky-header="true" with a scrollable container:

ID Name Email Status
001 Alice Johnson alice@example.com Active
002 Bob Smith bob@example.com Active
003 Carol White carol@example.com Pending
004 David Brown david@example.com Active
005 Eve Davis eve@example.com Inactive
006 Frank Wilson frank@example.com Active
<div class="omni-table-responsive" style="max-height: 400px; overflow-y: auto;">
  <table class="omni-table" data-sticky-header="true">
    <!-- ... -->
  </table>
</div>

Responsive Container

Use omni-table-responsive wrapper for horizontal scrolling on small screens:

Column 1 Column 2 Column 3 Column 4 Column 5 Column 6
Data 1-1 Data 1-2 Data 1-3 Data 1-4 Data 1-5 Data 1-6
Data 2-1 Data 2-2 Data 2-3 Data 2-4 Data 2-5 Data 2-6

Responsive Cards

Use data-responsive="cards" to transform rows into cards on mobile. Add data-label attributes to cells:

Name Email Role Status
Alice Johnson alice@example.com Admin Active
Bob Smith bob@example.com User Active
Carol White carol@example.com Editor Pending
<table class="omni-table" data-responsive="cards">
  <thead>
    <tr>
      <th>Name</th>
      <th>Email</th>
      <th>Role</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td data-label="Name">Alice Johnson</td>
      <td data-label="Email">alice@example.com</td>
      <td data-label="Role">Admin</td>
    </tr>
  </tbody>
</table>

Row Headers

Use <th scope="row"> for row headers:

Metric Q1 Q2 Q3 Q4
Revenue $250K $310K $285K $340K
Users 12,500 15,200 14,100 18,900

API Reference

Attribute Values Default Description
data-striped true Alternating row background colors
data-hover true Highlight rows on hover
data-bordered true Full borders on all cells
data-borderless true Remove all borders
data-size sm, md, lg, dense md Cell padding and font size
data-sticky-header true Fixed header when scrolling (requires wrapper)
data-responsive cards Transform to card layout on mobile
data-sortable Indicates sortable column (on <th>, requires Tier 2 JS)

Cell Attributes

Attribute Element Description
data-label <td> Label for responsive card mode
scope="row" <th> Marks row header cell
aria-sort <th> Indicates sort direction (ascending, descending, none)

Helper Classes

Class Description
omni-table-responsive Wrapper for horizontal scrolling

Accessibility

  • Use <thead>, <tbody>, and <tfoot> to structure tables properly
  • Use <th> elements for all header cells (column and row headers)
  • Add scope="row" to row header cells for clear relationships
  • Include <caption> to describe the table's purpose (visually hidden by default)
  • Use data-label attributes for responsive card mode to maintain context
  • Sortable columns (Tier 2) use aria-sort to announce sort state
  • High contrast mode increases border width for better visibility
  • Avoid nested tables - use proper grouping instead
  • Ensure sufficient color contrast in custom cells (4.5:1 minimum)

Components Used

Other OmniUI components demonstrated on this page: