This template makes a table's column headers stick to the top of the screen as the table's data is scrolled in and out of view. It only works on sortable tables.

It is recommended for use on very tall tables that have column headers that might be difficult to remember as you scroll through its data.

Standard usage

Include this template above the table by adding ((sticky header)). Add the sticky-header class to the table's wikitext.

((Sticky header))
{| class="wikitable sortable sticky-header"|}

Example with simple column headers:

((Sticky header))
{| class="wikitable sortable sticky-header"
|+ Caption
|-
! Name !! A !! B !! C
|-
! Red
| 1 || 2 || 3
|-
! Lime
| 4 || 5 || 6
⫶
|}

Example with multi-row column headers, ((static row numbers)), and ((sorting row)):

((Static row numbers))
((Sticky header))
{| class="wikitable sortable static-row-numbers sticky-header"
|+ Caption
|-
! rowspan=2 | Name
! colspan=3 | Data columns
|-
! A !! B !! C
|- ((Sorting row|4))
! Red
| 1 || 2 || 3
|-
! Lime
| 4 || 5 || 6
⫶
|}

Table with subsection headers

Problem: Note that the top subsection is sticky since it is just another header row.

The solution is to add a narrow blank line in front of the top subsection, and then it is no longer sticky:

((Sticky header))
{| class="wikitable sortable sticky-header"
|+ Caption
|-
! Name !! A !! B !! C
|-
| || || || 
|-
! colspan=4 |Subsection 1
|-
! Red
| 1 || 2 || 3
|-
! Lime
| 4 || 5 || 6
|-
! colspan=4 |Subsection 2
|-
...

Single-row header with class=sorttop

After sorting, rows using sortable's sorttop class are top-sticky along with the column headers. See the problem:

If this is undesirable, the only fix is to remove the sticky-header class from the table and add the sticky class. Note that its placement is different. See the fix:

Cumulative COVID-19 deaths. Jan 1, 2021
Date First case Jan 1
World 1,472,363
Days to double 112
Countries and territories 196
 USA March 3, 2020 335,789
 Brazil March 19, 2020 193,875
 India March 13, 2020 148,994
((mw-datatable))((sticky header))((table alignment))
{| class="wikitable sortable mw-datatable col1left col2left" style=text-align:right;
|+Cumulative COVID-19 deaths. Jan 1, 2021
|- class=sticky
!Date!!First case!!Jan 1
|- class="sorttop static-row-header"
|World || ||1,472,363
|- class="sorttop static-row-header"
|Days to double || ||112
|- class="sorttop static-row-header"
|Countries and territories || ||196
|-
...

Multi-row header followed by rows with totals

This requires class=sticky-header. The state, federal, and U.S. total rows move to the bottom of the table when the columns are sorted. This is because they use class=sortbottom. Reload the page to move them back to the top. Rows with totals are more useful when they are at the top. But those 3 rows cannot use class=sorttop in a table with a multi-row header, or those 3 rows would be sticky. This would take up too much vertical space, leaving little room for the table, especially in cell phones.

An alternative is to remove class=sortbottom. This way the 3 rows sort, and they come back to the top without reloading the page.

((mw-datatable))((static row numbers))((sticky header))
{| class="wikitable sortable mw-datatable sticky-header static-row-numbers" style=text-align:right;
|+ 2015 incarceration counts. Rates per 100,000 of all ages.
|- 
! Jurisdiction!! colspan=3 |Counts!! colspan=2 |Rate
|-
! !!Total!!Male!!Female!!Male!!Female
|- ((sort row|6)) 
|- class="static-row-header sortbottom" style="font-weight:bold; text-align:right;"
| style=text-align:left | State || 1,949,400 || 1,759,700 || 189,800 || 1,450 || 150
|- class="static-row-header sortbottom"  style="font-weight:bold; text-align:right;"
| style=text-align:left | Federal || 195,700 || 182,800 || 12,900 || 150 || 10
|- class="static-row-header sortbottom"  style="font-weight:bold; text-align:right;"
| style=text-align:left | U.S. total || 2,145,100 || 1,942,500 || 202,600 || 1,600 || 160
...

Known issues

Tested in browsers on Windows 10, Windows 11, iOS 17 (iphone SE 2020), and Android 13 (Samsung Galaxy S21).

Tall column headers blocking too much data:

See also