Skip to content

Tables ​

Table is provided as CSS-only utilities. No JavaScript required.

Installation ​

sh
npm install agnosticui-core
sh
yarn add agnosticui-core
sh
pnpm add agnosticui-core
sh
bun add agnosticui-core

Import Styles ​

css
/* In your CSS/SCSS file */
@import "agnosticui-core/styles/table.css";

Or in your JavaScript:

javascript
import "agnosticui-core/styles/table.css";

Default Variant ​

Clean, standard look with light header background and subtle borders.

Employee Directory
NameEmailRoleStatus
Camilla Rodriguezcamilla@enchilada.mxDesignerActive
Jonathan Chenjonathan@la-chispa.ioEngineerActive
Sarah Kimsarah@example.comProduct ManagerAway
Marcus Johnsonmarcus@example.comDeveloperActive
Total Employees4
Show HTML
html
<table class="ag-table">
  <caption>
    Employee Directory
  </caption>
  <thead>
    <tr>
      <th>Name</th>
      <th>Email</th>
      <th>Role</th>
      <th>Status</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Camilla Rodriguez</td>
      <td>camilla@enchilada.mx</td>
      <td>Designer</td>
      <td>Active</td>
    </tr>
    <tr>
      <td>Jonathan Chen</td>
      <td>jonathan@la-chispa.io</td>
      <td>Engineer</td>
      <td>Active</td>
    </tr>
    <tr>
      <td>Sarah Kim</td>
      <td>sarah@example.com</td>
      <td>Product Manager</td>
      <td>Away</td>
    </tr>
    <tr>
      <td>Marcus Johnson</td>
      <td>marcus@example.com</td>
      <td>Developer</td>
      <td>Active</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="3">Total Employees</td>
      <td>4</td>
    </tr>
  </tfoot>
</table>

Variants ​

Stacked (Stronger Hierarchy) ​

Stronger hierarchy with darker header. Good for dense data or when you want clear separation.

Q4 2024 Sales Report
RegionRevenueGrowthTarget
North America$2.4M+12%Met
Europe$1.8M+8%Met
Asia Pacific$3.1M+15%Exceeded
Total$7.3M+11%-
Show HTML
html
<table class="ag-table ag-table--stacked">
  <caption>
    Q4 2024 Sales Report
  </caption>
  <thead>
    <tr>
      <th>Region</th>
      <th>Revenue</th>
      <th>Growth</th>
      <th>Target</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>North America</td>
      <td>$2.4M</td>
      <td>+12%</td>
      <td>Met</td>
    </tr>
    <tr>
      <td>Europe</td>
      <td>$1.8M</td>
      <td>+8%</td>
      <td>Met</td>
    </tr>
    <tr>
      <td>Asia Pacific</td>
      <td>$3.1M</td>
      <td>+15%</td>
      <td>Exceeded</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>Total</td>
      <td>$7.3M</td>
      <td>+11%</td>
      <td>-</td>
    </tr>
  </tfoot>
</table>

Minimal (Ultra-light) ​

Ultra-light, airy feel. No header background, just a strong border. Great for dashboards.

System Status
ServiceStatusUptimeResponse Time
API Gateway✓ Operational99.9%120ms
Database✓ Operational99.8%45ms
Cache Server✓ Operational99.95%8ms
Show HTML
html
<table class="ag-table ag-table--minimal">
  <caption>
    System Status
  </caption>
  <thead>
    <tr>
      <th>Service</th>
      <th>Status</th>
      <th>Uptime</th>
      <th>Response Time</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>API Gateway</td>
      <td>✓ Operational</td>
      <td>99.9%</td>
      <td>120ms</td>
    </tr>
    <tr>
      <td>Database</td>
      <td>✓ Operational</td>
      <td>99.8%</td>
      <td>45ms</td>
    </tr>
    <tr>
      <td>Cache Server</td>
      <td>✓ Operational</td>
      <td>99.95%</td>
      <td>8ms</td>
    </tr>
  </tbody>
</table>

Monochrome (High Contrast) ​

High contrast, bold look. Inverted header colors for editorial/sophisticated feel.

Product Comparison
FeatureBasicProEnterprise
Users525Unlimited
Storage10GB100GB1TB
SupportEmailPriority24/7 Dedicated
Show HTML
html
<table class="ag-table ag-table--monochrome">
  <caption>
    Product Comparison
  </caption>
  <thead>
    <tr>
      <th>Feature</th>
      <th>Basic</th>
      <th>Pro</th>
      <th>Enterprise</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Users</td>
      <td>5</td>
      <td>25</td>
      <td>Unlimited</td>
    </tr>
    <tr>
      <td>Storage</td>
      <td>10GB</td>
      <td>100GB</td>
      <td>1TB</td>
    </tr>
    <tr>
      <td>Support</td>
      <td>Email</td>
      <td>Priority</td>
      <td>24/7 Dedicated</td>
    </tr>
  </tbody>
</table>

Size Variants ​

Small ​

Compact padding, ideal for dense data.

Compact Data
IDNameStatus
001Item AActive
002Item BPending
003Item CActive
Show HTML
html
<table class="ag-table ag-table--small">
  <caption>
    Compact Data
  </caption>
  <thead>
    <tr>
      <th>ID</th>
      <th>Name</th>
      <th>Status</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>001</td>
      <td>Item A</td>
      <td>Active</td>
    </tr>
    <tr>
      <td>002</td>
      <td>Item B</td>
      <td>Pending</td>
    </tr>
    <tr>
      <td>003</td>
      <td>Item C</td>
      <td>Active</td>
    </tr>
  </tbody>
</table>

Medium (Default) ​

Standard padding for most use cases.

Default Size
NameEmailRole
Alice Smithalice@example.comDeveloper
Bob Jonesbob@example.comDesigner
Show HTML
html
<table class="ag-table">
  <caption>
    Default Size
  </caption>
  <thead>
    <tr>
      <th>Name</th>
      <th>Email</th>
      <th>Role</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Alice Smith</td>
      <td>alice@example.com</td>
      <td>Developer</td>
    </tr>
    <tr>
      <td>Bob Jones</td>
      <td>bob@example.com</td>
      <td>Designer</td>
    </tr>
  </tbody>
</table>

Large ​

Generous padding for readability and emphasis.

Spacious Layout
CategoryValueChange
Revenue$2.4M+15%
Expenses$1.2M-5%
Show HTML
html
<table class="ag-table ag-table--large">
  <caption>
    Spacious Layout
  </caption>
  <thead>
    <tr>
      <th>Category</th>
      <th>Value</th>
      <th>Change</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Revenue</td>
      <td>$2.4M</td>
      <td>+15%</td>
    </tr>
    <tr>
      <td>Expenses</td>
      <td>$1.2M</td>
      <td>-5%</td>
    </tr>
  </tbody>
</table>

Modifiers ​

All modifiers can be combined freely with variants and sizes.

Striped ​

Alternating row colors for easier scanning.

Striped rows for easier scanning
NameEmailRole
Alice Smithalice@example.comDeveloper
Bob Jonesbob@example.comDesigner
Carol Whitecarol@example.comManager
David Browndavid@example.comEngineer
Show HTML
html
<table class="ag-table ag-table--striped">
  <caption>
    Striped rows for easier scanning
  </caption>
  <thead>
    <tr>
      <th>Name</th>
      <th>Email</th>
      <th>Role</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Alice Smith</td>
      <td>alice@example.com</td>
      <td>Developer</td>
    </tr>
    <tr>
      <td>Bob Jones</td>
      <td>bob@example.com</td>
      <td>Designer</td>
    </tr>
    <tr>
      <td>Carol White</td>
      <td>carol@example.com</td>
      <td>Manager</td>
    </tr>
    <tr>
      <td>David Brown</td>
      <td>david@example.com</td>
      <td>Engineer</td>
    </tr>
  </tbody>
</table>

Bordered ​

Clear cell separation with borders around all cells.

Clear cell separation with borders
ProductPriceQuantity
Widget A$29.9950
Widget B$49.9925
Widget C$19.99100
Show HTML
html
<table class="ag-table ag-table--bordered">
  <caption>
    Clear cell separation with borders
  </caption>
  <thead>
    <tr>
      <th>Product</th>
      <th>Price</th>
      <th>Quantity</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Widget A</td>
      <td>$29.99</td>
      <td>50</td>
    </tr>
    <tr>
      <td>Widget B</td>
      <td>$49.99</td>
      <td>25</td>
    </tr>
    <tr>
      <td>Widget C</td>
      <td>$19.99</td>
      <td>100</td>
    </tr>
  </tbody>
</table>

Hoverable ​

Interactive rows with hover effect.

Interactive rows with hover effect
TaskAssigneeStatus
Update documentationAliceIn Progress
Review pull requestsBobPending
Deploy to productionCarolComplete
Show HTML
html
<table class="ag-table ag-table--hoverable">
  <caption>
    Interactive rows with hover effect
  </caption>
  <thead>
    <tr>
      <th>Task</th>
      <th>Assignee</th>
      <th>Status</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Update documentation</td>
      <td>Alice</td>
      <td>In Progress</td>
    </tr>
    <tr>
      <td>Review pull requests</td>
      <td>Bob</td>
      <td>Pending</td>
    </tr>
    <tr>
      <td>Deploy to production</td>
      <td>Carol</td>
      <td>Complete</td>
    </tr>
  </tbody>
</table>

Combination Examples ​

Striped + Bordered + Hoverable ​

All modifiers combined
NameDepartmentSalaryYears
Emma WilsonEngineering$95,0003
James LeeDesign$85,0002
Olivia MartinezProduct$105,0005
Liam ChenMarketing$75,0001
Average$90,0002.75
Show HTML
html
<table
  class="ag-table ag-table--striped ag-table--bordered ag-table--hoverable"
>
  <caption>
    All modifiers combined
  </caption>
  <thead>
    <tr>
      <th>Name</th>
      <th>Department</th>
      <th>Salary</th>
      <th>Years</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Emma Wilson</td>
      <td>Engineering</td>
      <td>$95,000</td>
      <td>3</td>
    </tr>
    <tr>
      <td>James Lee</td>
      <td>Design</td>
      <td>$85,000</td>
      <td>2</td>
    </tr>
    <tr>
      <td>Olivia Martinez</td>
      <td>Product</td>
      <td>$105,000</td>
      <td>5</td>
    </tr>
    <tr>
      <td>Liam Chen</td>
      <td>Marketing</td>
      <td>$75,000</td>
      <td>1</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="2">Average</td>
      <td>$90,000</td>
      <td>2.75</td>
    </tr>
  </tfoot>
</table>

Stacked + Small + Striped ​

Compact stacked table with stripes
IDTaskPriority
1Fix login bugHigh
2Update docsMedium
3Refactor APILow
4Add testsHigh
Show HTML
html
<table class="ag-table ag-table--stacked ag-table--small ag-table--striped">
  <caption>
    Compact stacked table with stripes
  </caption>
  <thead>
    <tr>
      <th>ID</th>
      <th>Task</th>
      <th>Priority</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Fix login bug</td>
      <td>High</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Update docs</td>
      <td>Medium</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Refactor API</td>
      <td>Low</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Add tests</td>
      <td>High</td>
    </tr>
  </tbody>
</table>

Minimal + Large + Hoverable ​

Spacious minimal table with hover
MetricThis MonthLast Month
Active Users12,45011,230
Page Views89,34082,100
Conversions1,2341,089
Show HTML
html
<table class="ag-table ag-table--minimal ag-table--large ag-table--hoverable">
  <caption>
    Spacious minimal table with hover
  </caption>
  <thead>
    <tr>
      <th>Metric</th>
      <th>This Month</th>
      <th>Last Month</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Active Users</td>
      <td>12,450</td>
      <td>11,230</td>
    </tr>
    <tr>
      <td>Page Views</td>
      <td>89,340</td>
      <td>82,100</td>
    </tr>
    <tr>
      <td>Conversions</td>
      <td>1,234</td>
      <td>1,089</td>
    </tr>
  </tbody>
</table>

Monochrome + Bordered + Striped + Hoverable ​

Maximum combination example
MonthSalesExpensesProfit
January$125,000$85,000$40,000
February$132,000$88,000$44,000
March$148,000$92,000$56,000
April$155,000$95,000$60,000
Total$560,000$360,000$200,000
Show HTML
html
<table
  class="ag-table ag-table--monochrome ag-table--bordered ag-table--striped ag-table--hoverable"
>
  <caption>
    Maximum combination example
  </caption>
  <thead>
    <tr>
      <th>Month</th>
      <th>Sales</th>
      <th>Expenses</th>
      <th>Profit</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>January</td>
      <td>$125,000</td>
      <td>$85,000</td>
      <td>$40,000</td>
    </tr>
    <tr>
      <td>February</td>
      <td>$132,000</td>
      <td>$88,000</td>
      <td>$44,000</td>
    </tr>
    <tr>
      <td>March</td>
      <td>$148,000</td>
      <td>$92,000</td>
      <td>$56,000</td>
    </tr>
    <tr>
      <td>April</td>
      <td>$155,000</td>
      <td>$95,000</td>
      <td>$60,000</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>Total</td>
      <td>$560,000</td>
      <td>$360,000</td>
      <td>$200,000</td>
    </tr>
  </tfoot>
</table>

Accessibility ​

Visually Hidden Caption ​

Caption is accessible to screen readers but hidden visually using the .visually-hidden utility class.

User account information
UsernameEmailLast Login
john_doejohn@example.com2 hours ago
jane_smithjane@example.com5 minutes ago
Show HTML
html
<table class="ag-table ag-table--minimal ag-table--hoverable">
  <caption class="visually-hidden">
    User account information
  </caption>
  <thead>
    <tr>
      <th>Username</th>
      <th>Email</th>
      <th>Last Login</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>john_doe</td>
      <td>john@example.com</td>
      <td>2 hours ago</td>
    </tr>
    <tr>
      <td>jane_smith</td>
      <td>jane@example.com</td>
      <td>5 minutes ago</td>
    </tr>
  </tbody>
</table>

A Note on Web Components and Shadow DOM ​

It's important to note that by opting for a CSS-only solution, table styling will participate in the global CSS cascade. This design decision, however, allows us to fully leverage the native power and accessibility of the <table> element without the complexities and limitations that a Shadow DOM wrapper would impose.

You might wonder why Table is not provided as a web component, which is a common pattern for other components in this library. The short answer is that the benefits of Shadow DOM (style encapsulation) create significant, deal-breaking problems for styling complex, multi-part elements like tables.

This is a deliberate architectural choice, and the reasoning is shared by authors of other popular libraries like Shoelace.

The Declarative Dream vs. The Styling Nightmare ​

Ideally, a table web component would let you write familiar, declarative HTML using slots:

html
<!-- A hypothetical <ag-table> component -->
<ag-table variant="striped" size="large">
  <!-- The user declaratively provides the table structure -->
  <table>
    <thead>
      <tr>
        <th>...</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>...</td>
      </tr>
    </tbody>
  </table>
</ag-table>

This looks great! However, the problem arises when the <ag-table> component tries to apply styles based on its properties (like variant="striped"). The component's internal stylesheet, encapsulated in its Shadow DOM, cannot reliably style the deeply nested <tr> or <td> elements that you've passed into the slot.

The ::slotted() CSS selector is not powerful enough for this. It can only target top-level slotted elements and cannot reach their descendants. This means we could not style the inner parts of your table from our component.

The Unacceptable Alternatives ​

To work around this styling limitation, we would be forced into one of two poor solutions:

  1. A Massive API of CSS Parts: We could require you to add a part attribute to every single element (<tr part="row">, <td part="cell">, etc.) so we could style them. This is extremely verbose and places a heavy burden on you, the consumer.
  2. Abandoning Declarative Slots: The other option is to abandon slots and force you to pass in your data as a JavaScript array (e.g., items="..."). The component would then render the table itself. This is inflexible, works poorly for server-rendered content, and prevents you from using the semantic <table> markup you know and love.

The CSS-First Solution ​

Given these challenges, the best solution is to embrace CSS as a first-class citizen. By providing a suite of well-designed CSS classes that you can apply directly to a standard <table> element, we give you:

  • Total Flexibility: Use standard, semantic HTML.
  • Unrestricted Styling: Target any element with standard CSS selectors.
  • Framework Agnosticism: It works everywhere, from vanilla HTML to any JavaScript framework.

This approach leverages the native power and accessibility of the <table> element without the unnecessary complexity and limitations that a Shadow DOM wrapper would impose.


Design Tokens ​

All table styles use AgnosticUI design tokens for colors, spacing, and typography. Customize the look by overriding CSS variables:

css
:root {
  --ag-background-secondary: #f3f4f6;
  --ag-space-3: 0.875rem;
  --ag-border-subtle: #d1d5db;
  --ag-text-primary: #111827;
}

[data-theme="dark"] {
  --ag-background-secondary: #212730;
  --ag-border-subtle: #656c76;
  --ag-text-primary: #f0f6fc;
}

Class Reference ​

ClassDescription
.ag-tableBase table class (required)
.ag-table--stackedDark header variant
.ag-table--minimalLight, borderless header
.ag-table--monochromeHigh contrast black/white header
.ag-table--smallCompact padding
.ag-table--largeGenerous padding
.ag-table--stripedZebra striping on rows
.ag-table--borderedBorders around all cells
.ag-table--hoverableHover effect on rows