Fluid scrollable table

This javascript and CSS application lets you scroll a fluid table while the header and (optional) footer sections stay fixed. Other solutions I've seen on the web require explicit table column widths, but that's not necessary here.

Browser support

Tested to work in:

Should degrade gracefully as a static HTML table in older browsers, or if javascript is not used.

Demo

Try zooming or resizing the browser window, and the widths of the fixed and scrollable columns should still match, regardless of table shape.

Simple table

This table lacks a TFOOT, so there's no fixed bottom section.

header header header text that may wrap in narrow windows
row 1 (first) row 1 row 1
row 2 row 2 text that may wrap in narrow windows row 2
row 3 row 3 row 3
row 4 row 4 row 4
row 5 row 5 row 5
row 6 row 6 row 6
row 7 row 7 row 7
row 8 row 8 row 8
row 9 row 9 row 9
row 10 row 10 row 10
row 11 row 11 row 11
row 12 row 12 row 12
row 13 row 13 row 13
row 14 row 14 row 14
row 15 row 15 row 15
row 16 row 16 row 16
row 17 row 17 row 17
row 18 row 18 row 18
row 19 row 19 row 19
row 20 (last) with text that may wrap in narrow windows row 20 row 20

Advanced table

This table contains optional CAPTION, THEAD, TBODY and TFOOT elements. Thanks to the TFOOT, it gets a fixed footer section.

Caption sample text
header header header text that may wrap in narrow windows
row 1 (first) row 1 row 1
row 2 row 2 text that may wrap in narrow windows row 2
row 3 row 3 row 3
row 4 row 4 row 4
row 5 row 5 row 5
row 6 row 6 row 6
row 7 row 7 row 7
row 8 row 8 row 8
row 9 row 9 row 9
row 10 row 10 row 10
row 11 row 11 row 11
row 12 row 12 row 12
row 13 row 13 row 13
row 14 row 14 row 14
row 15 row 15 row 15
row 16 row 16 row 16
row 17 row 17 row 17
row 18 row 18 row 18
row 19 row 19 row 19
row 20 (last) row 20 row 20
footer text that may wrap in narrow windows footer footer

How it works

This scrollable table is based on identical copies of the original table (cloned by the script): one for the fixed header section, one for the scrollable section and one for the optional fixed footer section.

Each table copy is placed in a DIV container (created by the script), which in turn is placed in a cell in an outer container table (also created by the script). If a CAPTION element is used in the original table, it's moved to the outer container table. The table structure and CLASS names created by the script should look like this:

<table class="scrollable_container">
<tr>
<td class="header_td">
<div class="fixed_header">
	<table>...</table>
</div>
</td>
</tr>
<tr>
<td class="scrollable_td">
<div class="scrollable">
	<table>...</table>
</div>
</td>
</tr>
<tr>
<td class="footer_td">
<div class="fixed_footer">
	<table>...</table>
</div>
</td>
</tr>
</table>

In each table copy, only the part relevant for its own section is shown:

The parts of a table not relevant to its section are styled with CSS to be both invisible and use as little vertical space as possible, while still being able to influence table column width. Note that these parts must not be removed from the table with e.g. javascript or CSS display: none;, their presence is needed to affect layout and get correct column widths.

Version without javascript

It's possible to create a scrollable table without javascript, but then you need to insert the table copies in the static HTML, and you must style the scrollable DIV and TABLE elements manually, which in turn means that the scrollable section can't adapt to varying header or footer heights automatically. I don't recommend this.

Installation and configuration

To make a table scrollable, give it the custom DATA attribute data-scrollable-table. Multiple scrollable tables can be used on the same page.

Fixed header and footer

The fixed header contains the table's THEAD section, or the first table row if no THEAD exists. If you want more than one table row in the fixed header you need to put the rows in a THEAD section.

To make a fixed footer you need a TFOOT section. In HTML 4.01 the TFOOT element must be placed directly after the THEAD element in the table's HTML structure (despite being rendered at the bottom of the table), but HTML 5 also allows TFOOT at the end of the table.

Width and height

Width values are optional.

The scrollable section's height can be changed with the div.scrollable selector in the stylesheet (this DIV element is generated by the script, it can't be seen in the static HTML).

The fixed section heights are calculated automatically by the script.

Advanced table markup

CAPTION, THEAD, TFOOT and TBODY elements are optional, but a TFOOT is needed to get a fixed footer.

Cells in the same THEAD, TBODY or TFOOT section can be spanned with COLSPAN and/or ROWSPAN, but without a THEAD the first table row is used for the fixed header, which means it can't span the scrollable cells in subsequent rows.

Styling the table with CSS

The tables in the header, scrollable and footer sections can be styled in various ways, including border-spacing, padding and border (for the cells), and the script should still be able to calculate heights accurately.

Outer table styling like border or margin can be applied to the (javascript-generated) container table with the table.scrollable_container selector.

Accessibility pitfalls

There are several accessibility pitfalls to consider with this scrollable table:

published: Nov 6, 2015
last modified: Jan 26, 2017