Tables are fundamental in web applications for displaying structured data. Adding features like a scrollable header and frozen (sticky) columns can make tables even more user-friendly. In this article, we’ll explore how to create a table with a sticky header and a frozen left column using pure HTML and CSS.
To see the code in action, check out this live example on CodePen:
This example of code uses JS class to make a table. You can replicate this with any framework or library of your choice.
We use a simple table structure with a for the header and a
for the rows. The table is wrapped in a div for scrollability. Here's the code:<div> <h2> CSS for Sticky Header and Frozen Column </h2> <p>Here’s the CSS that makes the magic happen:<br> </p> <pre class="brush:php;toolbar:false">/* General styles */ body { font-family: Arial, sans-serif; } /* Scrollable container */ .table-container { border: 1px solid #e5e7eb; border-bottom: none; overflow: auto; /* Enables both horizontal and vertical scrolling */ height: 400px; /* Limits table height for vertical scrolling */ } /* Table layout */ .table { border-collapse: collapse; width: 100%; table-layout: fixed; /* Ensures consistent column widths */ } /* Table cells and headers */ .table th, .table td { padding: 8px; text-align: center; border: 1px solid #e5e7eb; } /* Frozen first column */ .table td:nth-child(1), .table th:nth-child(1) { background: red; /* Highlighted background for frozen column */ position: sticky; left: 0; /* Ensures the column stays on the left */ z-index: 5; /* Keeps the column above other cells */ color: white; } /* Add higher z-index for header */ .table th:nth-child(1) { z-index: 6; } /* Sticky header */ .table th { background-color: #1e3a8a; color: white; font-size: 14px; font-weight: bold; position: sticky; top: 0; /* Makes the header stick to the top */ z-index: 2; /* Keeps the header above the table body */ } /* Styling for table body */ .table td { font-size: 14px; color: #6b7280; } /* Zebra striping for rows */ .table tr:nth-child(odd) { background-color: #f9fafb; } /* Hover effect for rows */ .table tr:hover { background-color: rgba(14, 116, 144, 0.1); } /* No data row styling */ .no-data { text-align: center; font-size: 14px; color: #9ca3af; }
The .table-container class adds overflow: auto to enable both horizontal and vertical scrolling. The height: 400px property limits the height of the table, ensuring vertical scrolling for larger datasets.
The position: sticky and top: 0 properties are applied to
The first column is styled using nth-child(1) selectors for
The background color for the frozen column is set to red, with white text for better visibility. You can customize this to match your design preferences.
As you scroll vertically, the position: sticky header remains at the top of the .table-container.
When scrolling horizontally, the leftmost column remains fixed, creating a frozen column effect.
The combination of overflow: auto and position: sticky ensures the table remains functional and user-friendly across both axes.
Responsive Adjustments:
Use media queries to adjust the column widths and table layout for smaller screens.
Use JavaScript to fetch and populate rows dynamically for larger datasets.
Add row click events, filtering, or sorting using JavaScript to enhance functionality.
Using the standard