![]() | This template is used on approximately 6,400 pages and changes may be widely noticed. Test changes in the template's /sandbox or /testcases subpages, or in your own user subpage. Consider discussing changes on the talk page before implementing them. |
![]() | This template uses TemplateStyles: |
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's used on tall tables that have column headers that might be difficult to remember as you scroll through the data. If you want a table to be both top-sticky and side-sticky see {{sticky table start}}.
Usage
Include this template by adding {{sticky header}}
or its redirect {{sticky-header}}
above a table. Add one of the following classes to the table start wikitext.
Class | Summary |
---|---|
sticky-header
|
Make the first header row top sticky. |
sticky-header-multi
|
Requires sortable table. Make multiple header rows top sticky. Avoid use with the sorttop class that becomes sticky after sorting. Avoid making headers sticky that aren't for the entire table (ex. section header rows). Avoid making excessively tall header rows sticky that might block too much data on short screens (ex. mobile landscape).
|
Single sticky header row
The sticky-header
class is used to make the first header row top sticky. Sortable is not required. sorttop
and sortbottom
are not a problem with single header rows.
Color | A | B | C |
---|---|---|---|
Max | 10 | 11 | 12 |
Red | 1 | 2 | 3 |
Lime | 4 | 5 | 6 |
Gold | 7 | 8 | 9 |
Blue | 10 | 11 | 12 |
Total | 22 | 26 | 30 |
{{sticky header}}
{| class="wikitable sortable sticky-header"
|+ Caption
|-
! Color !! A !! B
! class="unsortable" | C
|- class=sorttop
| '''Max''' || 10 || 11 || 12
|-
| Red || 1 || 2 || 3
|-
| Lime || 4 || 5 || 6
|-
| Gold || 7 || 8 || 9
|-
| Blue || 10 || 11 || 12
|- class=sortbottom
| '''Total''' || 22 || 26 || 30
|}
Multiple sticky header rows
The sticky-header-multi
class is used to make multiple header rows top sticky. Sortable table is required since sortable is currently the only way to move consecutive rows of column headers to the <thead>
element. If some or all columns should not be sortable, then class=unsortable
can be put in the header cell with the sorting icon. Table top will still be sticky. See Help:Sortable tables. If JavaScript is disabled, then sortable and this solution won't work.
Sorttop versus sortbottom
Avoid using the sorttop
class since sortable moves those rows into the <thead>
element after sorting, which makes them top sticky too. A solution might be to move them to the bottom and use the sortbottom
class instead.
Color | Data | ||
---|---|---|---|
A | B | C | |
Red | 1 | 2 | 3 |
Lime | 4 | 5 | 6 |
Gold | 7 | 8 | 9 |
Blue | 10 | 11 | 12 |
Max | 10 | 11 | 12 |
Total | 22 | 26 | 30 |
{{sticky header}}
{| class="wikitable sortable sticky-header-multi"
|+ Caption
|-
! rowspan=2 | Color
! colspan=3 | Data
|-
! A !! B
! class="unsortable" | C
|-
| Red || 1 || 2 || 3
|-
| Lime || 4 || 5 || 6
|-
| Gold || 7 || 8 || 9
|-
| Blue || 10 || 11 || 12
|- class=sortbottom
| '''Max''' || 10 || 11 || 12
|- class=sortbottom
| '''Total''' || 22 || 26 || 30
|}
Row starts off at top and moves to bottom after sorting
This table excerpt is adapted from List of countries by tariff rate. sortbottom
is used instead of sorttop
for the "World" row. So the World row does not become sticky after sorting. After sorting it moves to the bottom with the regional rows.
Country/Territory/Region/Group | WB | WTO | UNCTAD | |||
---|---|---|---|---|---|---|
Tariff rate, applied, weighted mean, all products | Year | Simple average applied MFN tariff, all products | Year | Import tariff rates on non-agricultural and non-fuel products | Year | |
![]() |
2.59% | 2017 | ||||
![]() |
0% | 2021 | 10.80% | 2021 | ||
![]() |
0% | 2018 | 6.5% | 2018 | 0% | 2018 |
![]() |
0% | 2021 | 10.9% | 2021 | 0% | 2021 |
![]() |
13.14% | 2021 | ||||
Low & middle income economies (WB) | 4.28% | 2017 | ||||
Low-income economies (WB) | 9.79% | 2017 | ||||
Middle-income economies (WB) | — | |||||
Upper middle income economies (WB) | 3.70% | 2017 | ||||
High-income economies (WB) | 2.02% | 2017 | ||||
European Union | 1.39% | 2021 | 5.2% | 2021 | 1.49% | 2021 |
Header rows not for whole table
Consecutive rows of column headers are top sticky, so avoid adding a row of headers right under the column headers that don't apply to the entire table such as a section header meant to visually separate the table.
A solution might be to move each section to a column or separate tables, which also avoids accessibility issues per MOS:COLHEAD.
Another solution might be to add a blank row of data cells (| colspan=4 |
) between the last column header row and the first section header row so the latter is not included in the consecutive header rows.
Color | Data | ||
---|---|---|---|
A | B | C | |
Section 1 | |||
Red | 1 | 2 | 3 |
Lime | 4 | 5 | 6 |
Section 2 | |||
Gold | 7 | 8 | 9 |
Blue | 10 | 11 | 12 |
{{sticky header}}
{| class="wikitable sortable sticky-header-multi"
|+ Caption
|-
! rowspan=2 | Color
! colspan=3 | Data
|-
! A !! B !! C
|-
| colspan=4 |
|-
! colspan=4 | Section 1
|-
| Red || 1 || 2 || 3
|-
| Lime || 4 || 5 || 6
|-
! colspan=4 | Section 2
|-
| Gold || 7 || 8 || 9
|-
| Blue || 10 || 11 || 12
|}
Excessively tall header rows
Avoid excessively tall header rows that might block too much or all data when sticky on a small mobile screen, especially in landscape orientation. Some solutions might be to move some of the header text to the table caption, more concise header text, remove line-breaks (<br>
) in the headers, or split the table up into smaller tables to reduce headers.
Header group 1 | |||
---|---|---|---|
Header group 2 |
Header group 3 | ||
Header 1 |
Header 2 |
Header 3 |
Header 4 |
data | data | data | data |
data | data | data | data |
data | data | data | data |
data | data | data | data |
data | data | data | data |
data | data | data | data |
data | data | data | data |
data | data | data | data |
Multi-row header that can't be visibly sortable
This table is adapted from here: AptX#Variants. It uses class=sortable in order to have a sticky multi-row header, but all columns individually use class=unsortable.
None of the columns can be sortable because the type of info and data within any single column varies greatly, and there is no point in ordering it alphabetically or numerically. Plus sorting any column removes the rowspans in the first column which gives the overall order of the table.
SBC (for reference) |
aptX | aptX LL | aptX HD | aptX Adaptive | Audio CD (for reference) | ||||
---|---|---|---|---|---|---|---|---|---|
@ 279 kbit/s | @ 420 kbit/s | @ up to ~1.2 Mbit/s | |||||||
misc. | Launch | ? | < 2009 | 2012 | 2016 | 2018 | 2021 | 1980s | |
Trademark | – | Qualcomm (until August 2015: CSR, until July 2010: APT Licensing Ltd., until March 2005: Solid State Logic) |
– | ||||||
Related patents | EP 0400755B1 (expired) | EP 0398973B1 (revoked) | aptX, US 9398620B1 (expired) |
aptX | ? | – | |||
Free implementations | FFmpeg, libsbc | FFmpeg, libopenaptx | FFmpeg, libopenaptx | FFmpeg, libopenaptx | N/A | – | |||
Proprietary implementations | Multiple | Qualcomm libaptX | None | Qualcomm libaptXHD | ? | – | |||
Chip | – | CSR8635 | CSR8670 | CSR8675 | QCC5100 | – | |||
Audio Encoding |
Word depth | ? | 16-bit | 16-bit | 16-bit 24-bit |
24-bit | 16-bit | 16-bit | |
Sampling rate | 44.1 kHz 48 kHz |
44.1 kHz 48 kHz |
44.1 kHz 48 kHz |
44.1 kHz 48 kHz |
44.1 kHz 48 kHz 96 kHz |
44.1 kHz | 44.1 kHz | ||
Bit rate | 345 kbit/s (@ 48 kHz) | 352 kbit/s (@ 44.1 kHz) 384 kbit/s (@ 48 kHz) |
352 kbit/s (@ 48 kHz) | 576 kbit/s (24 bits @ 48 kHz) | 279 kbit/s | 420 kbit/s | ~140 kbit/s to 1.2 mbit/s (content dependent) | 1411 kbit/s (@ 44.1 kHz) | |
Constant | Constant | Constant | Constant | Variable | Variable | Constant | |||
Codec latency | ? | 1.8 – 2.0 ms | ? | 1.8 – 2.0 ms | 1.4 – 2.0 ms | ? | – | ||
Hardware transmitter latency | ? | ? | ≈ 40 ms (using dedicated antenna) |
? | ≈ 80 ms | ? | – | ||
Software transmitter latency (most phones) | 200 – 500 ms depending on the transmitting device |
– | |||||||
Backwards compatible with | – | SBC | SBC, aptX | SBC, aptX | SBC, aptX, aptX HD | ? | ? | ||
Sound quality |
THD+N @ 1 kHz | −67 dB or −85 dB? | −85 dB | -80 dB or −90 dB? | −90 dB | −100 dB | −96 dB | −96 dB | |
Multi-tone @ 1 kHz | −100 dB | ? | −100 dB | −90 dB | −100 dB | ? | |||
Multi-tone @ 10 kHz | −65 dB | ? | −90 dB | −85 dB | −95 dB | ? | |||
Crosstalk | −120 dB | ? | −155 dB | −90 dB | −200 dB | ? | |||
SNR @ 1 kHz | 93 dB | 93 dB | 129 dB | 130 dB | 135 dB | −96 dB | −96 dB | ||
PEAQ ODG | −0.18 or −0.08? | ? | 0.05 or 0.04? | −0.06 | 0.045 | ? | |||
Frequency response over Bluetooth | 20 Hz – 22.7 kHz | 20 Hz – 22.7 kHz | 20 Hz – 22.7 kHz | 20 Hz – 22.7 kHz | 20 Hz – 22 kHz | 20 Hz – 22 kHz |
Known issues
See page of narrow sticky tables for testing in cell phones, etc.. As of Aug 9, 2025 {{Sticky header}} is not working in iPhone SE 2020 with the latest iOS (18.6) in the latest versions of Safari, Chrome, Firefox, Edge, and Opera.
Tested in browsers on Windows 10, Windows 11, iOS 18 (iphone SE 2020), iOS 17 (iPhone 14 Pro Max), and Android 14 (Samsung Galaxy S21).
- Avoid wrapping a sticky table in an element that has an overflow style or it won't stick to the top of the page and the headers will be pushed down some in certain circumstances. Example of what not to do:
<div style="overflow: auto;"></div>
. Avoid settingoverflow
,overflow-y
, oroverflow-x
to "auto", "scroll", or "hidden". - When {{Anchor}} (or a similar anchor mechanism; see WP:ANCHOR) is used to link to a part of a top-sticky table, the link's target is moved to the top of the page behind the top-sticky elements. The target can be partially or fully covered depending on the height of the target and the top-sticky elements.
- In the Timeless skin at any width or other skins at <=639px width screens, tables wider than the main content area have a horizontal scroll. When those tables are sticky, the tables overflow past the content area causing layout issues and the horizontal scroll does not work. Therefore, sticky headers are disabled for <=639px width screens and Timeless overflowed tables per Wikipedia's guidelines to maintain accessibility for all users.
- On Android phones (any skin, any screen size), sticky table headers are not sticky when a table is wider than the screen (viewport), forcing users to zoom out before headers become sticky—at the cost of readability. This issue is more common in portrait orientation, where the screen is narrowest. The root problem is how Android browsers handle the Visual Viewport API (VVA) during zoom: sticky positioning uses the layout viewport, while rendering is based on the visual viewport, causing sticky headers to become unsynchronized.[1][2] See Visual vs. Layout Viewport Demo. This is an unresolved limitation on Android browsers like Chrome and Firefox. The only known workaround is setting
minimum-scale=1
in the meta viewport tag,[3] which Wikipedia purposely sets to 0.25 and allows horizontal scrolling on smaller screens. - On Safari 14.1.2, a top-sticky thead (
sticky-header-multi
class) is flush to the top of the page, but a sticky row (sticky-header
class) is not with a gap above it. This is most likely a layout bug in how Safari 14 calculates sticky positioning for rows relative to the table's edge, not the viewport top. This is not an issue in Safari 16.6.1.
See also
- Help:Table/Advanced § Tables with sticky headers
- {{sticky table start}} - allows sticky rows and columns inside a scrollable area.
- {{shy}} – Can be used to help narrow columns by adding a soft hyphen to a word to allow it to wrap.
More template styles for tables:
- {{sort under}} - moves the sorting arrows under the headers.
- {{row hover highlight}} - adds row hover highlighting, and option for white background.
- {{static row numbers}} - adds a column of row numbers to a table.
- {{table alignment}} - aligns the cells in a column, or a whole table.