Interactive
Data table
Sorting by column (numbers, money and dates sort as such), a filter box, pagination, row selection with checkboxes and Shift for ranges, a column menu and a sticky header, on top of an existing table. Needs monsoon.js.
Needs monsoon.js. The styles work on their own, and the behavior comes from the optional interactive layer: add <script src="https://cdn.jsdelivr.net/npm/monsooncss/dist/monsoon.js" defer></script> or import 'monsooncss/js'. See the interactive layer.
Example
<div class="data-table" data-m-data-table data-m-data-table-page-size="5" data-m-data-table-select>
<table class="table table-hover">
<thead><tr><th>Invoice</th><th>Customer</th><th>Status</th><th>Issued</th><th>Amount</th></tr></thead>
<tbody>
<tr><td class="font-medium">INV-1042</td><td>Northwind</td><td data-sort="Paid"><span class="badge badge-sm badge-success">Paid</span></td><td>2026-09-02</td><td class="tabular-nums">$1,250.00</td></tr>
<tr><td class="font-medium">INV-1043</td><td>Globex</td><td data-sort="Pending"><span class="badge badge-sm badge-warning">Pending</span></td><td>2026-09-05</td><td class="tabular-nums">$860.00</td></tr>
<tr><td class="font-medium">INV-1044</td><td>Initech</td><td data-sort="Overdue"><span class="badge badge-sm badge-danger">Overdue</span></td><td>2026-09-09</td><td class="tabular-nums">$2,410.00</td></tr>
<tr><td class="font-medium">INV-1045</td><td>Umbrella</td><td data-sort="Paid"><span class="badge badge-sm badge-success">Paid</span></td><td>2026-09-12</td><td class="tabular-nums">$395.00</td></tr>
<tr><td class="font-medium">INV-1046</td><td>Hooli</td><td data-sort="Paid"><span class="badge badge-sm badge-success">Paid</span></td><td>2026-09-15</td><td class="tabular-nums">$12,000.00</td></tr>
<tr><td class="font-medium">INV-1047</td><td>Stark Industries</td><td data-sort="Pending"><span class="badge badge-sm badge-warning">Pending</span></td><td>2026-09-18</td><td class="tabular-nums">$4,780.50</td></tr>
<tr><td class="font-medium">INV-1048</td><td>Wayne Enterprises</td><td data-sort="Paid"><span class="badge badge-sm badge-success">Paid</span></td><td>2026-09-21</td><td class="tabular-nums">$990.00</td></tr>
<tr><td class="font-medium">INV-1049</td><td>Acme</td><td data-sort="Overdue"><span class="badge badge-sm badge-danger">Overdue</span></td><td>2026-09-24</td><td class="tabular-nums">$75.00</td></tr>
<tr><td class="font-medium">INV-1050</td><td>Soylent</td><td data-sort="Pending"><span class="badge badge-sm badge-warning">Pending</span></td><td>2026-09-27</td><td class="tabular-nums">$3,300.00</td></tr>
<tr><td class="font-medium">INV-1051</td><td>Cyberdyne</td><td data-sort="Paid"><span class="badge badge-sm badge-success">Paid</span></td><td>2026-10-01</td><td class="tabular-nums">$18,450.00</td></tr>
<tr><td class="font-medium">INV-1052</td><td>Tyrell</td><td data-sort="Paid"><span class="badge badge-sm badge-success">Paid</span></td><td>2026-10-04</td><td class="tabular-nums">$640.00</td></tr>
<tr><td class="font-medium">INV-1053</td><td>Massive Dynamic</td><td data-sort="Pending"><span class="badge badge-sm badge-warning">Pending</span></td><td>2026-10-08</td><td class="tabular-nums">$2,050.00</td></tr>
</tbody>
</table>
</div>JavaScript API
Attribute
data-m-data-table
Options
| Option | Description |
|---|---|
data-m-data-table-page-size="10" (0 shows every row) | |
data-m-data-table-select | |
data-m-data-table-filter="false" | |
data-m-data-table-columns="false" | |
data-sort on a cell, data-sortable="false" on a header |
Methods
| Method | Description |
|---|---|
Monsoon.dataTable(el).sort(1, "descending") | |
Monsoon.dataTable(el).filter("paid") | |
Monsoon.dataTable(el).page(2) | |
Monsoon.dataTable(el).selected | |
Monsoon.dataTable(el).selectAll() | |
Monsoon.dataTable(el).refresh() |
Events
| Event | Description |
|---|---|
monsoon:table-sort { column, direction } | |
monsoon:table-filter { query, count } | |
monsoon:table-page { page, size } | |
monsoon:table-select { rows } |
Classes
18 classes. Click a name to copy it. Utilities on the same element always win over component defaults, so any of them can be adjusted with plain utility classes.
| Class | Type | What it does |
|---|---|---|
| Base | Base class of the data table. On a <div> in the example. Sets grid display, gap, width and background, and --data-table-height.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets flex display, alignment and gap.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets alignment and width.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets margin, text size, font weight and text color.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets fixed position, offsets, stacking order, margin, padding and overflow, and --tone and --tone-fg.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets flex display, alignment, gap, padding, corner radius and pointer cursor.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets height, overflow, background, border, corner radius and sticky position.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets inline-flex display, alignment, gap, margin, padding and text size.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets width, height, background and opacity.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets width, padding and grid display.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets padding, text style and text color.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets flex display, alignment, gap, text size and text color.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. A hook for state rules such as .data-table-info.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets flex display, alignment, gap and width.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets width and text style.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets text size.CSS |
|
| Part | Part of the data table. On a <table> in the example. Sets width, border, text size, padding, text style and background, and --table-py and --table-px.CSS |
|
| Modifier | Modifier, combined with the data-table class. Not used in the example above. Sets inline-grid display, alignment, width, height, text color and background, and 9 custom properties.CSS |
Usage
The styles ship inside the same stylesheet as the utilities, and the behavior comes from the optional monsoon.js script, which enhances any element with a matching data-m attribute, including markup added later.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/monsooncss">
<script src="https://cdn.jsdelivr.net/npm/monsooncss/dist/monsoon.js" defer></script>
<!-- Data table: start from the base class, then add modifiers -->
<div class="data-table" data-m-data-table data-m-data-table-page-size="5" data-m-data-table-select>
<table class="table table-hover">
<thead><tr><th>Invoice</th><th>Customer</th><th>Status</th><th>Issued</th><th>Amount</th></tr></thead>
<tbody>
<tr><td class="font-medium">INV-1042</td><td>Northwind</td><td data-sort="Paid"><span class="badge badge-sm badge-success">Paid</span></td><td>2026-09-02</td><td class="tabular-nums">$1,250.00</td></tr>
<tr><td class="font-medium">INV-1043</td><td>Globex</td><td data-sort="Pending"><span class="badge badge-sm badge-warning">Pending</span></td><td>2026-09-05</td><td class="tabular-nums">$860.00</td></tr>
<tr><td class="font-medium">INV-1044</td><td>Initech</td><td data-sort="Overdue"><span class="badge badge-sm badge-danger">Overdue</span></td><td>2026-09-09</td><td class="tabular-nums">$2,410.00</td></tr>
<tr><td class="font-medium">INV-1045</td><td>Umbrella</td><td data-sort="Paid"><span class="badge badge-sm badge-success">Paid</span></td><td>2026-09-12</td><td class="tabular-nums">$395.00</td></tr>
<tr><td class="font-medium">INV-1046</td><td>Hooli</td><td data-sort="Paid"><span class="badge badge-sm badge-success">Paid</span></td><td>2026-09-15</td><td class="tabular-nums">$12,000.00</td></tr>
<tr><td class="font-medium">INV-1047</td><td>Stark Industries</td><td data-sort="Pending"><span class="badge badge-sm badge-warning">Pending</span></td><td>2026-09-18</td><td class="tabular-nums">$4,780.50</td></tr>
<tr><td class="font-medium">INV-1048</td><td>Wayne Enterprises</td><td data-sort="Paid"><span class="badge badge-sm badge-success">Paid</span></td><td>2026-09-21</td><td class="tabular-nums">$990.00</td></tr>
<tr><td class="font-medium">INV-1049</td><td>Acme</td><td data-sort="Overdue"><span class="badge badge-sm badge-danger">Overdue</span></td><td>2026-09-24</td><td class="tabular-nums">$75.00</td></tr>
<tr><td class="font-medium">INV-1050</td><td>Soylent</td><td data-sort="Pending"><span class="badge badge-sm badge-warning">Pending</span></td><td>2026-09-27</td><td class="tabular-nums">$3,300.00</td></tr>
<tr><td class="font-medium">INV-1051</td><td>Cyberdyne</td><td data-sort="Paid"><span class="badge badge-sm badge-success">Paid</span></td><td>2026-10-01</td><td class="tabular-nums">$18,450.00</td></tr>
<!-- the full example is in the Code tab above -->Theme it with --seed on any ancestor, for example style="--seed: #0d9488", and force a scheme with class="dark" or class="light" on a wrapper.
Accessibility
- Keep real table markup with
th scopeheaders and acaption(visually hidden if needed) so screen readers can navigate by row and column. - Every interactive part shows a visible focus ring with
:focus-visible, and tone colors pair with-foregroundtokens that keep text at 4.5:1 or better in light and dark mode.