Explain Codes LogoExplain Codes Logo

How can I let a table's body scroll but keep its head fixed in place?

html
responsive-design
sticky-headers
table-layout
Anton ShumikhinbyAnton Shumikhin·Feb 10, 2025
TLDR

To create a scrollable body with a fixed header in a table, use CSS properties. Wrap your table in a container div with a set height and overflow-y: auto. Set display: block for the <tbody>, and adjust its height to define the scrolling area. Here's a quick example:

<style> .fixed-header { height: 150px; /* Defines the container's height */ overflow-y: auto; /* Lets the magic happen */ } .fixed-header tbody { display: block; /* Block level element */ height: 120px; /* Scroll area; adjust for fun! */ overflow-y: auto; /* More magic! */ } </style> <div class="fixed-header"> <table> <thead><tr><th>Column 1</th><th>Column 2</th></tr></thead> <tbody> <tr><td>Data 1</td><td>Data 2</td></tr> <!-- More data rows, unlimited buffet! --> </tbody> </table> </div>

This code creates a scrollable tbody under a static thead, marrying functionality and space efficiency. Feel free to fiddle with the heights to fit your needs.

Creating a dynamic scroll area

To dynamically adapt the scroll area's height based on content or viewport, use JavaScript:

function adjustTableBodyHeight() { // Get that tbody var tableBody = document.querySelector('.fixed-header tbody'); // Grab the available view height, minus offset for any fancy headers or footers var availableHeight = window.innerHeight - tableBody.getBoundingClientRect().top; // Subtract more for larger fancy things // Set tbody height to be that available height (but not less than 100px because we're not animals) tableBody.style.height = Math.max(availableHeight, 100) + 'px'; } // Fire when the document loads. James Bond style. window.onload = adjustTableBodyHeight; // And any time the window gets resized. Because we're fancy like that. window.onresize = adjustTableBodyHeight;

With this, you can create an Excel-like, scrollable table body with all-you-can-eat scroll rows.

Styling a sticky table header

To simulate the Excel-styled fixed headers, you can also achieve similar functionality using CSS position: sticky;:

<style> .sticky-header th { position: sticky; /* Sticky as a Post-it note */ top: 0; /* Stick to the top */ background-color: #fff; /* Don't show the mess behind */ } </style> <table class="sticky-header"> <thead> <tr><th>Column 1</th><th>Column 2</th></tr> </thead> <tbody> <tr><td>Data 1</td><td>Data 2</td></tr> <!-- More data rows. Now also with infinite desserts! --> </tbody> </table>

The position: sticky; CSS property ensures the table header stays on top like a favorite sticky-note.

Responsiveness for all screens

Ensuring responsiveness in times of multi-device viewing is key to good web design. Your fixed header and scrollable body table should look good and work well across devices. Use media queries to adjust your table's size and styling for different screen sizes:

@media (max-width: 768px) { // Not all heroes wear capes. Some just adjust table sizes. .fixed-header, .sticky-header th { width: 100%; } .fixed-header tbody { max-height: 80px; /* Shorter scroll area for smaller screens */ } }

Debugging misaligned columns

To handle common issues like misaligned columns, set table-layout: fixed; in your CSS and define widths for <th> tags. Also consider the cross-browser compatibility of properties like position: sticky; - because not all browsers adventure as boldly into the future as others.

Accessibility and usability

For accessibility, validate that your table can be easily navigated with assistive technologies and keyboard. Semantic HTML tags and attributes ensure screen reader friendliness, and careful design can help retain usability even with high-contrast modes and style overrides.