Table Snippets — Free HTML CSS JS Data Tables & Grids
22 table components · Data Table, Sortable, Comparison, Schedule, Expandable, Leaderboard, Pagination, Editable, Gantt · Exports to React, Vue, Angular & Tailwind
What's included
Features
About this tool
Table Snippets — Free Data Tables, Sortable Columns, Comparison Matrix & Schedule Grid
Tables display structured data — user records, product inventories, pricing feature comparisons, and weekly schedules. A well-designed data table with search, sort, and clear visual hierarchy helps users find what they need in seconds. A poorly designed one forces scrolling, misreads, and frustration. This collection covers the four most common table patterns used in production web products.
Every snippet is plain HTML, CSS, and minimal vanilla JavaScript with no library dependencies.
Data Table gives you a user management table with gradient avatar initials, status badges (Active/Away/Offline with pulsing dots), live full-text search across all columns simultaneously, a select-all checkbox, Edit and Remove row actions, and pagination controls. The filterTable() function uses row.textContent — which returns every visible character in the row as one string — for a single .includes() check that searches all columns at once.
Sortable Table adds click-to-sort on any column header. The sortBy() function reads data-col (column index) and data-type ("string" or "number") from the clicked th, compares cell values using Array.sort(), and re-appends rows in sorted order. The data-val attribute on numeric cells stores the raw number separately from the formatted display value (e.g. data-val="89" on a cell showing "$89.00") so currency symbols and units do not break numeric comparison.
Comparison Table is the standard pricing feature matrix: three plan columns (Starter / Pro / Team) with the featured Pro column highlighted via accent borders applied to every cell in the column, section row dividers that span the full table width to group feature categories, .yes (✓ green) and .no (✗ grey) indicators for included and excluded features, and plan CTA buttons in the table footer. The featured column uses a continuous border achieved by applying .featured to every individual td — not a wrapper overlay.
Schedule / Timetable renders a weekly calendar grid — days as columns (Mon–Fri), hourly time slots as rows — with six colour-coded event types, a today column highlight (class on header and cells), and horizontal scroll for narrow screens. Event blocks fill cell height via height: 100%. Multi-hour events use rowspan. The layout is a plain HTML table — no CSS Grid, no Flexbox — which gives perfectly aligned columns and rows for calendar data.
Combine snippets: add the filterTable() function from Data Table to Sortable Table for a search + sort data grid. Use the Comparison Table above a Pricing Toggle for an interactive pricing page section.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
filterTable(q) reads row.textContent on each tbody tr. The textContent property returns every visible text character in the entire row concatenated as one string — name, email, role, department, status, and date all in one. A single .toLowerCase().includes(term) check matches any of them. Rows that do not match get the .hidden class (display: none). Rows that do match have .hidden removed. No per-column selector, no column index mapping, no multiple checks.
Cells with formatted numeric values use a data-val attribute to store the raw number separately: data-val="89.99" on a cell showing "$89.99". The sort function reads parseFloat(cell.dataset.val) for numeric columns instead of cell.textContent. parseFloat("$89.99") returns NaN, but parseFloat("89.99") returns 89.99. This technique works for any format — currency symbols, unit labels, percentage signs, or comma-separated thousands.
The .featured class is applied to every individual td in the Pro column — in every tbody row and the tfoot row. Each .featured cell gets border-left: 1.5px solid #6366f1 and border-right: 1.5px solid #6366f1. Because table cells are vertically adjacent with border-collapse: collapse, the borders line up seamlessly to form one continuous vertical line. The last row adds border-bottom and the header adds border-top to complete the box.
Yes. Both functions operate on the same tbody tr elements independently and do not conflict. Copy the filterTable() function and search input HTML from the Data Table snippet into the Sortable Table. Both functions iterate the same rows — filter hides non-matching rows and sort reorders all rows. The sort function respects the hidden rows because re-appending all rows resets their position, but the .hidden class persists and hides non-matching rows after each sort.