Reputation: 8742
As you might know, position: sticky;
has landed in Webkit (demo).
So far I can see this only works within the parent element. But I'd like to know if I can use this in a scrolling div with a table.
So it needs to 'listen' on the scrolling event of the div
, not the table
.
I know I can do this with javascript and absolute positioning, but I was wondering if the sticky-positioning
would support this.
Upvotes: 66
Views: 129335
Reputation: 148
If you need sticky header for chrome only then you can set position: sticky; top: some_value
(top
property is mandatory) for td
element in a thead
element.
See:
<table border=1>
<thead>
<tr>
<td style='position: sticky; top: -1px;background: red'>Sticky Column</td>
<td>Simple column</td>
</tr>
</thead>
Upvotes: 14
Reputation: 9229
Position sticky on thead th
works in 2018!
table { border-spacing: 1px; }
th, td { background: white; color: black; border: 1px solid black; }
thead th { position: sticky; top: 0; }
<table>
<thead>
<tr> <th>column 1 <th>column 2 <th>column 3 <th>column 4
</thead>
<tbody>
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
<tr> <td>data <td>data <td>data <td>data
</tbody>
</table>
Also, if you have multiple rows in <thead>
, you can select the first one to remain sticky:
thead tr:first-child th { position: sticky; top: 0; }
As of March 2018 support is pretty much there across modern browsers ref: https://caniuse.com/#feat=css-sticky
Credit goes to @ctf0 for this one (ref comment made 3 Dec 2017)
Upvotes: 133
Reputation: 5592
If it ain't working, adding a z-index to thead or th might help.
Upvotes: 0
Reputation: 1146
Setting the position:sticky for the thead is enough, no need to set it for th :
table.StickyHeader thead {
position: sticky;
top: 0px;
}
Tested in:
Edge 105.0.1343.42 , Firefox 105.0 , Chrome 105.0.5195.127 , Opera 91.0.4516.16
But, Firefox can not render borders of th when position of thead is set to sticky and th has background-color:
table.StickyHeader th {
border: 1px solid black;
padding: 5px;
background-color: gold;
text-align: center;
}
Upvotes: 7
Reputation: 682
Caution:
position:sticky
doesn't work anymore on Google Chrome in 2019, try to use fixed
instead or display:inline-block
Upvotes: -1
Reputation: 8742
As it turns out it position: sticky
only works in the window and not in a scrolling div.
I created a test-case with a very long table with a table header:
h1 {
font-size: 18px;
font-weight: bold;
margin: 10px 0;
}
div.testTable {
height: 200px;
overflow: auto;
}
table.stickyHead thead {
position: -webkit-sticky;
top: 0px;
background: grey;
}
table.stickyHead td,
table.stickyHead th {
padding: 2px 3px;
}
<h1>Position sticky</h1>
<div class="testTable">
<table class="stickyHead">
<thead>
<tr>
<th>column 1</th>
<th>column 2</th>
<th>column 3</th>
<th>column 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
</tbody>
</table>
</div>
As you can see, if you remove the overflow from the wrapper and make your window not so tall, the table-head is sticking to the top of the window. I doesn't apply to the wrapping div
even if you make give the div
position: relative
Upvotes: 4
Reputation: 16692
position: sticky
doesn't work with table elements (as long as their display
attribute starts with table-
) since tables are not part of specification:
Other kinds of layout, such as tables, "floating" boxes, ruby annotations, grid layouts, columns and basic handling of normal "flow" content, are described in other modules.
Edit: As Jul 2019 according to https://caniuse.com/#feat=css-sticky Firefox supports this feature and Chrome has at least support for <th>
tag.
Upvotes: 11