Sortable Data Table
A data table with sortable header buttons, a rotating direction arrow and a subtle column highlight: rows re-order with GSAP Flip so each one visibly travels to its new place.
About This Component
A sortable table that shows its work. Clicking a header sorts the column, clicking it again reverses it, and the direction arrow rotates rather than swapping glyph. The rows do not blink into a new order: GSAP Flip records where each one was, the rows are re-appended in their new sequence, and every row tweens from its old position to its new one, so a row that jumps from bottom to top is watched all the way up. The sorted column keeps a wash of the variant's accent, which is what makes the movement legible.
Read the full effect overview
Above the table a text field narrows the rows, staggering the survivors back in and counting what is left. The header is sticky, so the column names stay put while the body scrolls.
The markup is a real table with a caption, scope on every header and aria-sort kept in step, so it is readable and sortable from the keyboard and still a sensible table with the script removed. One HTML file, one stylesheet, one script, vanilla JavaScript, GSAP and the Flip plugin, no framework. Ships in three looks, vault, corporate and glass, switched with one data-variant attribute.
What's Included
- Header buttons sort ascending, then descending, with a rotating arrow
- Rows re-order with Flip so each one travels to its new position
- Subtle accent wash on whichever column is sorted
- Text filter that narrows rows with a stagger and counts what is left
- Sticky header over a scrolling body
- Numbers and dates sort on data-value, text sorts on what is rendered
- Real table markup with caption, scope and aria-sort kept in step
- Three shipped variants: vault, corporate, glass
Perfect For
- Admin and dashboard tables of accounts, orders or users
- Pricing, spec and comparison tables that readers want to re-rank
- Reporting views where a column sort is the main interaction
- Any table where a re-order currently happens in one invisible frame
How It Works
Flip on table rows
A sort records Flip.getState over every row, re-appends the rows to the tbody in their new order, then hands the state to Flip.from with a small stagger. Flip's absolute option is deliberately not used here: taking a tr out of the table's own layout collapses the columns, and rows of equal height travel perfectly well on transforms alone.
Sort values and the column wash
A cell's data-value wins when it exists, so a formatted number like 14,200 and a relative date like 2d ago both sort as numbers, while the text columns sort on what is actually rendered. After each sort the cells of the active column take an is-sorted class that paints them with the variant's accent at low opacity, and the header's aria-sort attribute is set to ascending or descending so assistive technology reports the same thing the arrow shows.
Filtering
The field tests the query against each row's whole text and toggles the hidden attribute, which the stylesheet restates as display:none so it beats the hover rule. The surviving rows are then staggered back in from a small horizontal offset with clearProps, so nothing inline is left behind for the next Flip to measure against.