Data Tables Snippets — Free HTML CSS JS Sortable Data Table Examples

85 snippets tagged Data Tables · Live preview · Exports to React, Vue, Angular & Tailwind

What's included

Features

Sortable, multi-sortable and filterable tables with live search highlighting
Frozen columns, sticky headers and sticky summary rows
Inline editing, validation errors and row-level actions
Row selection, bulk action bars and expandable detail panels
Virtualisation, pagination, and explicit loading, empty and error states

About this tag

Data Tables Snippets — 85 Free Sortable Data Table Examples

Tables are where dense data meets real interaction, and the details decide whether one is usable: which column is sorted, what stays pinned when you scroll, how a long row reveals its detail, and what happens when the data is empty, loading or broken.

These snippets cover the full working set — sorting, multi-sort, filtering, search highlighting, frozen and resizable columns, inline editing, row selection, expandable detail panels, virtualisation for large sets, and the loading, empty and error states most implementations forget.

Sorting state has to be visible, not just functional

A sortable column needs its current direction shown in the header — an arrow indicating ascending or descending — and exposed programmatically via aria-sort, not just handled correctly on click. Multi-sort extends this with a visible priority indicator per column, because a user who shift-clicks a second column to add a tiebreaker needs to see that the first sort is still active underneath it.

Frozen and sticky, without breaking scroll

A frozen first column and a sticky header both rely on position: sticky combined with a defined stacking context, and the tricky part is keeping cell borders and shadows consistent as content scrolls underneath — a shadow that only appears once the frozen column has something to separate itself from is what sells the effect rather than looking like a static line.

Editing inline versus a modal round trip

Inline editing with per-cell validation lets a small correction happen without navigating away from the table's context, which matters most in admin tools where the table itself is the primary interface. The validation for each cell needs to behave like a real form field — an error message, an aria-invalid state, a way to cancel back to the previous value — not just a visual red border on the cell.

Virtualisation is a performance tool, not a default

Rendering only the rows currently in the viewport keeps a table with thousands of rows responsive, but it also breaks native browser find-in-page and complicates row-height-dependent layouts. Below roughly a few hundred rows, the DOM cost is negligible and the added complexity of virtualisation is not worth its trade-offs; above it, rendering only the visible window is what keeps scrolling and re-rendering fast.

States a table can be in besides "has data"

A loading skeleton shaped like the eventual table, an empty state that suggests why there is nothing to show and what to do about it, and an error state distinct from an empty one are each a deliberate design decision — and each is a state these snippets implement explicitly rather than leaving as an afterthought discovered in production.

Real-world uses

Common Use Cases

Admin and back-office tools
The table is usually the product here, so sorting, filtering and inline edit are core, not extras.
Reporting and export views
Grouped rows, summary rows and print views are what turn a table into something a person can hand over.
Editable data grids
Inline editing with per-cell validation avoids a modal round trip for every small correction.
Responsive table patterns
Card-per-row on mobile keeps a wide table readable without a horizontal scroll nobody discovers.

Got questions?

Frequently Asked Questions

Once the DOM node count starts hurting — roughly a few hundred rows with several cells each. Below that, virtualisation adds complexity and breaks Ctrl+F for no real gain. Above it, rendering only the visible window is the difference between instant and unusable.

Use real table markup with <th> and the right scope attributes, put sort controls in <button>s inside the header cells, and expose the current sort with aria-sort. A grid of divs needs the entire grid role pattern reimplemented to reach the same baseline.

Either a horizontal scroll container with the first column frozen, or transform each row into a stacked card with labels. Scroll suits comparison across columns; cards suit reading one record at a time. Both beat shrinking text until it is illegible.

No. Every snippet is plain HTML, CSS and vanilla JavaScript that runs in any page — a static file, a WordPress theme, a Rails view, anything. When you do want a framework version, the editor exports each snippet as a React component, a React + Tailwind component, a standalone Tailwind HTML file, a Vue 3 single-file component or an Angular standalone component.

Yes — copy, modify and ship them in personal or commercial work, with no attribution required and no licence to track.

Yes. Every snippet opens in a live editor with separate HTML, CSS and JS panels and a preview that updates as you type. Check it at mobile, tablet and desktop widths, then copy the code or export it in your framework of choice.