A wide revenue report, months down the side and six regions plus a total across the top, that scrolls in both directions inside a fixed-height card while the header row and the month column stay in place. The scroll container has overflow auto and a maximum height of 340 pixels, the header cells use position sticky with top 0, and the month cells use position sticky with left 0. The corner cell sits above both with a higher z-index, and the frozen column casts a soft shadow on its right edge so it reads as a layer rather than a rendering fault. Months are row headers and the regions are column headers, so screen readers announce both for every figure. The container is a labelled region with tabindex 0, which lets keyboard users scroll it with the arrow keys. Use it for financial reports, schedules and comparison grids that are wider than the screen. In Bootstrap the frozen cells keep the inset shadow Bootstrap uses for row hover and add the edge shadow after it, so hover still works on the pinned column.
What’s included
Sticky header row and sticky first column
Edge shadow on the frozen column
Scrolls both ways inside a 340px high card
Month cells are row headers, regions are column headers
Keyboard-scrollable labelled region
Accessibility
The table has a caption, column headers with scope="col" and month row headers with scope="row", so each figure is announced with its month and region. The scroll container is a role="region" with an aria-label and tabindex="0", and it shows a 2px indigo outline on keyboard focus. Nothing animates.
Customise it
Set the visible height with max-height on the scroll container and the table width with min-width. The edge shadow is the 6px 0 8px -6px box-shadow on .pin (plain CSS and Bootstrap) or the shadow- utility on the month cells (Tailwind).