Data table with sticky header
A scrolling table that keeps its column headings, and sometimes its first columns, visible as the data moves.
See it
What it is
A data table with a sticky header keeps its column labels pinned while the rows scroll underneath. Wide versions may also freeze the first column, echoing the Freeze Panes behavior in Excel, so the row identity stays visible while the user scans across many fields.
Reach for it when a dense table extends beyond one viewport and people need the headings to interpret every cell. It is most useful for comparison, operations, and reporting tables, where losing the header turns a screen of values into guesswork.
Gotcha: position: sticky works relative to the nearest scrolling ancestor. Sticky cells need opaque backgrounds and deliberate z-index layers, especially where a frozen first column meets the header row. Keep native table semantics, and avoid cloning the header into a second table that can drift out of alignment or be read twice.
Ask AI for it
Build a semantic data table inside a max-height scroll container with overflow: auto. Use caption, thead, tbody, and th scope attributes. Apply position: sticky and top: 0 to every header cell, then freeze the first column with left: 0. Use border-collapse: separate and border-spacing: 0, opaque cell backgrounds, and three z-index layers so body row headers sit above cells, column headers sit above those, and the top-left intersection stays highest. Add visible row hover and :focus-visible states, and keep header and body columns aligned with one shared table layout.