Tables

Tables display structured data in rows and columns, making it easy to scan, compare, and analyze information. They’re essential for dashboards, admin panels, and data-heavy applications.


Installation

Copy the table CSS from styles/docs.css or include the Standard stylesheet:

<link rel="stylesheet" href="standard.min.css">

Then use table classes in your HTML:

<table class="Table">
  <thead>
    <tr>
      <th>Name</th>
      <th>Status</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Project Alpha</td>
      <td>Active</td>
    </tr>
  </tbody>
</table>

Usage

The base .Table class provides clean table styling with proper spacing and borders. Add modifier classes to enable features like striping, hover states, and responsive behavior.

Name Email Role
Alice Chen alice@example.com Admin
Bob Smith bob@example.com Editor
Carol Davis carol@example.com Viewer

Examples

Basic Table

A simple table with header row and body content. The base .Table class handles typography, spacing, and subtle borders.

Product Category Price Stock
Wireless Headphones Electronics $149.00 234
Ergonomic Keyboard Electronics $89.00 156
Standing Desk Mat Furniture $45.00 89

Striped Rows

Alternating row colors improve readability for large datasets. Add .Table--striped for zebra striping.

Date Description Amount Balance
Feb 1, 2026 Opening Balance $5,000.00
Feb 2, 2026 Wire Transfer +$2,500.00 $7,500.00
Feb 3, 2026 Software License -$299.00 $7,201.00
Feb 3, 2026 Office Supplies -$85.50 $7,115.50
Feb 4, 2026 Client Payment +$1,200.00 $8,315.50

Hoverable Rows

Highlight rows on hover for better focus. Add .Table--hoverable to enable hover states.

Employee Department Location Start Date
Emma Wilson Engineering San Francisco Jan 15, 2024
James Lee Design New York Mar 8, 2024
Sofia Martinez Marketing Austin Jul 22, 2024

Bordered Table

Full borders around all cells. Add .Table--bordered for a grid appearance.

Feature Free Pro Enterprise
Projects 3 Unlimited Unlimited
Team Members 1 10 Unlimited
Storage 1 GB 100 GB 1 TB
Support Community Email 24/7 Phone

Responsive / Scrollable Table

Wrap tables in .Table-wrapper for horizontal scrolling on small screens.

Order ID Customer Product Quantity Unit Price Total Status Date
#ORD-001 Acme Corp Widget Pro 50 $25.00 $1,250.00 Shipped Feb 1, 2026
#ORD-002 Tech Solutions Gadget Plus 25 $75.00 $1,875.00 Processing Feb 2, 2026
#ORD-003 Global Industries Device Max 100 $50.00 $5,000.00 Pending Feb 3, 2026

Sortable Headers

Add .Table--sortable and use .Table-sort buttons in headers. JavaScript handles the sorting logic.

Documents Feb 4, 2026
Images Feb 3, 2026
notes.md 4.2 KB Feb 2, 2026
readme.txt 1.8 KB Feb 1, 2026

Selectable Rows

Add checkboxes for row selection. Use .Table--selectable for proper alignment.

Name Type Size
project-v2.zip Archive 45.2 MB
design-specs.pdf Document 2.8 MB
logo-final.svg Image 128 KB
meeting-notes.docx Document 340 KB

Expandable Rows

Rows that expand to show additional details. Use .Table-expandBtn to toggle nested content.

Order Customer Total Status
#ORD-1234 John Doe $299.00 Complete
#ORD-1235 Jane Smith $549.00 Processing
Shipping Address: 123 Main St, New York, NY 10001
Items: Widget Pro (2), Gadget Plus (1)
Notes: Please leave at front door
#ORD-1236 Bob Johnson $125.00 Pending

Keep headers visible while scrolling long tables. Add .Table--stickyHeader and set a max-height on the wrapper.

ID Event User Timestamp
001 User Login alice@example.com 04:02:15
002 Page View alice@example.com 04:02:18
003 File Upload bob@example.com 04:03:22
004 Settings Change alice@example.com 04:05:01
005 User Logout bob@example.com 04:08:45
006 User Login carol@example.com 04:10:12
007 API Request system 04:12:33
008 Error system 04:15:00

Compact / Dense Table

Reduce padding for data-dense interfaces. Add .Table--compact for tighter spacing.

Key Value Type Updated
API_KEY sk_live_*** Secret 2h ago
DEBUG_MODE false Boolean 1d ago
MAX_UPLOAD_SIZE 10485760 Number 3d ago
TIMEZONE UTC String 7d ago

Table with Actions Column

Add action buttons in the last column for row-level operations.

User Email Role Status Actions
AC
Alice Chen
alice@example.com Admin Active
BS
Bob Smith
bob@example.com Editor Active
CD
Carol Davis
carol@example.com Viewer Inactive

Pagination

Combine tables with pagination controls for large datasets.

Invoice Client Amount Date Status
#INV-0042 Acme Corporation $3,450.00 Jan 28, 2026 Paid
#INV-0041 Tech Startup Inc $1,200.00 Jan 25, 2026 Paid
#INV-0040 Design Studio $890.00 Jan 22, 2026 Pending
#INV-0039 Marketing Agency $2,100.00 Jan 18, 2026 Overdue
#INV-0038 Consulting LLC $4,500.00 Jan 15, 2026 Paid
Showing 1-5 of 42 results
...

Common Patterns

Data Dashboard

Recent Orders
Order Customer Amount Status
#ORD-001 Acme Corp $1,250.00 Paid
#ORD-002 Tech Solutions $890.00 Pending
#ORD-003 Design Co $2,100.00 Overdue

Settings Key-Value Table

Setting Value
Language English (US)
Timezone UTC-8 (Pacific)
Date Format MM/DD/YYYY
Currency USD ($)

Comparison Table

Feature Free Pro Enterprise
Users 1 10 Unlimited
Storage 1 GB 100 GB 1 TB
Support Community Email 24/7 Phone

Customization

Override table styles using CSS custom properties:

/* Custom table colors */
.Table {
  --table-border-color: oklch(85% 0 0);
  --table-header-bg: oklch(97% 0 0);
  --table-stripe-bg: oklch(98% 0 0);
  --table-hover-bg: oklch(95% 0.02 250);
  --table-selected-bg: oklch(95% 0.05 250);
}

/* Dark mode overrides */
[data-theme="dark"] .Table {
  --table-border-color: oklch(30% 0 0);
  --table-header-bg: oklch(20% 0 0);
  --table-stripe-bg: oklch(18% 0 0);
  --table-hover-bg: oklch(25% 0.02 250);
  --table-selected-bg: oklch(25% 0.05 250);
}

/* Custom compact sizing */
.Table--extra-compact {
  --table-cell-padding-y: var(--space-1);
  --table-cell-padding-x: var(--space-2);
  font-size: 0.75rem;
}

/* Accent header row */
.Table--accent-header thead {
  background: var(--accent);
  color: white;
}

API Reference

Base Classes

Class Description
.Table Base table styles (required)
.Table-wrapper Responsive wrapper for horizontal scrolling
.Table-container Container with pagination area

Variant Classes

Class Description
.Table--striped Alternating row background colors
.Table--hoverable Highlight rows on hover
.Table--bordered Full borders around all cells
.Table--compact Reduced cell padding for dense data
.Table--stickyHeader Fixed header during vertical scroll
.Table--selectable Optimized for row selection with checkboxes
.Table--sortable Styled for sortable column headers
.Table--expandable Support for expandable row content

Row Classes

Class Description
.Table-row--selected Highlighted selected row state
.Table-row--expandable Row that can be expanded
.Table-row--expanded Currently expanded row
.Table-expandContent Row containing expanded content

Cell Classes

Class Description
.Table-checkbox Checkbox cell with proper alignment
.Table-actions Actions column (right-aligned)
.Table-expandCol Expand/collapse button column

Interactive Elements

Class Description
.Table-sort Sortable column header button
.Table-sort--active Currently sorted column
.Table-sortIcon Sort direction indicator icon
.Table-expandBtn Row expand/collapse button
.Table-expandBtn--open Expanded state for button

Pagination Classes

Class Description
.Table-pagination Pagination controls container
.Table-pageInfo "Showing X of Y" text
.Table-pageControls Page buttons container
.Table-pageBtn--active Current page button
.Table-pageEllipsis Ellipsis between page numbers

Utility Classes

Class Description
.Table-user User cell with avatar layout
.Table-fileIcon File/folder icon in cells
.Table-expandPanel Container for expanded content
.Table-expandDetail Individual detail item in expanded content
.Table-wrapper--scrollable Wrapper with vertical scroll (use with max-height)

CSS Reference

/* Base table */
.Table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
  color: var(--fg);
}

.Table th,
.Table td {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  border-bottom: 1px solid var(--bd);
}

.Table th {
  font-weight: 600;
  color: var(--fg);
  background: var(--bg-s);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Striped variant */
.Table--striped tbody tr:nth-child(even) {
  background: var(--bg-s);
}

/* Hoverable variant */
.Table--hoverable tbody tr:hover {
  background: oklch(95% 0.02 250 / 0.5);
}

/* Bordered variant */
.Table--bordered th,
.Table--bordered td {
  border: 1px solid var(--bd);
}

/* Compact variant */
.Table--compact th,
.Table--compact td {
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-xs);
}

/* Sticky header */
.Table--stickyHeader thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg);
}

/* Scrollable wrapper */
.Table-wrapper {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.Table-wrapper--scrollable {
  overflow-y: auto;
}

/* Selected rows */
.Table-row--selected {
  background: oklch(95% 0.05 250);
}

/* Checkbox column */
.Table--selectable .Table-checkbox {
  width: 40px;
  padding: var(--space-2);
}

/* Sort buttons */
.Table-sort {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-weight: 600;
  color: var(--fg);
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: var(--text-xs);
}

.Table-sort:hover {
  color: var(--accent);
}

.Table-sort--active {
  color: var(--accent);
}

.Table-sortIcon {
  font-size: 0.875rem;
  opacity: 0.5;
}

.Table-sort--active .Table-sortIcon {
  opacity: 1;
}

/* Expand/collapse */
.Table-expandCol {
  width: 40px;
  padding: var(--space-2);
}

.Table-expandBtn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--fg-3);
}

.Table-expandBtn:hover {
  color: var(--fg);
}

.Table-expandPanel {
  padding: var(--space-3) var(--space-4);
  background: var(--bg-s);
}

.Table-expandDetail {
  padding: var(--space-1) 0;
  font-size: var(--text-sm);
}

/* Actions column */
.Table-actions {
  text-align: right;
  white-space: nowrap;
}

/* User cell */
.Table-user {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* Pagination */
.Table-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--bd);
}

.Table-pageInfo {
  font-size: var(--text-sm);
  color: var(--fg-3);
}

.Table-pageControls {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.Table-pageBtn--active {
  font-weight: 600;
}

.Table-pageEllipsis {
  padding: 0 var(--space-1);
  color: var(--fg-3);
}

Accessibility

Keyboard Support

Key Action
Tab Move focus to next interactive element
Shift + Tab Move focus to previous interactive element
Space Toggle checkbox, activate sort button
Enter Activate buttons, expand/collapse rows
Arrow Keys Navigate within pagination controls

Screen Readers

<!-- Sortable header with proper ARIA -->
<th>
  <button class="Table-sort" aria-sort="ascending">
    Name
    <i class="ph ph-caret-up Table-sortIcon" aria-hidden="true"></i>
  </button>
</th>

<!-- Select all checkbox -->
<th class="Table-checkbox">
  <input type="checkbox" class="Checkbox" aria-label="Select all rows">
</th>

<!-- Expandable row -->
<button class="Table-expandBtn" 
        aria-expanded="false" 
        aria-controls="row-details-1"
        aria-label="Show details for Order #1234">
  <i class="ph ph-caret-right" aria-hidden="true"></i>
</button>

Caption and Summary

<table class="Table">
  <caption class="sr-only">
    User accounts showing name, email, role, and status.
  </caption>
  <!-- ... -->
</table>

Row Headers

<table class="Table">
  <thead>
    <tr>
      <th scope="col">Month</th>
      <th scope="col">Revenue</th>
      <th scope="col">Expenses</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">January</th>
      <td>$45,000</td>
      <td>$32,000</td>
    </tr>
  </tbody>
</table>

Best Practices

Do

  • Use tables for tabular data — Don’t use tables for layout
  • Keep columns scannable — Align numbers right, text left
  • Truncate long content — Use ellipsis or expand on hover
  • Show loading states — Skeleton rows or spinner for async data
  • Provide empty states — Clear message when no data exists
  • Make actions discoverable — Hover to reveal or always visible

Don’t

  • Overload with columns — 5-7 columns max for readability
  • Hide critical information — Key data should always be visible
  • Use inconsistent alignment — Pick one style and stick to it
  • Forget mobile — Use responsive wrapper or card layout
  • Skip keyboard support — All actions must be keyboard accessible
  • Nest tables — Use expandable rows instead