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

Share & Support

What's included

Features

Data table: textContent search across all columns in one .includes() check
Data table: select-all checkbox, gradient avatars, status badge dots, Edit/Remove actions
Sortable table: Array.sort + DOM re-append, data-type for string/numeric branch
Sortable table: data-val on cells stores raw number — handles "$89", "142 units"
Comparison table: .featured on every td in column = continuous accent border
Comparison table: section-row colspan dividers, .yes/.no indicators, footer plan CTAs
Schedule table: weekly grid, 6 event colour types, .today column, rowspan events
All tables: overflow-x:auto wrapper for horizontal scroll on narrow screens

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

User management, team directories, and subscriber tables
Data table for admin panels displaying team members, customers, or subscribers with status indicators, avatar initials, and per-row edit/remove actions. Wire the search input to a debounced API call for server-side filtering on large datasets.
SaaS pricing feature comparison matrix pages
Comparison table for plan feature matrices on pricing pages. The featured column accent, popular badge, and solid vs outline CTA differentiation are the three most effective visual cues for directing users to the recommended plan.
Product catalogues, inventory, and analytics reports
Sortable table for product listings, inventory management, and analytics report views. Click column headers to sort by price (lowest to highest), stock level (critical first), or date (most recent) — essential for any table where users need to find extremes.
Team scheduling, class timetables, and appointment booking
Schedule timetable for weekly team meeting overviews, university course timetables, appointment slot displays, and sprint planning calendar views. Colour-code events by category and highlight today automatically with the .today column class.
Learn Array.sort, textContent search, and table DOM patterns
Sortable table teaches Array.sort() with a custom comparator and DOM row reordering — a pattern that applies to any dynamic list. Data table teaches querySelectorAll + textContent for multi-column client-side search. Comparison table teaches the per-cell featured column border technique.
CSV export, API integration, and combined search plus sort
Wire the data table to a REST API endpoint for live data. Add CSV export via a Blob URL from visible row textContent. Combine filterTable() from the Data Table with sortBy() from the Sortable Table to build a full search + sort data grid in a single component.

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.