Reputation: 18891
I have a table. The only CSS I am adding to the standard Bootstrap library is the following to implement the sticky header:
.table-sticky th {
background: #fff;
position: sticky;
top: -1px;
z-index: 990;
}
<div class="table-responsive p-0 mt-2">
<table class="table table-sm table-striped table-hover table-sticky">
<thead>
<tr>
<th>#</th>
<th>Header</th>
<th>Header</th>
<th>Header</th>
<th>Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>1,001</td>
<td>Lorem</td>
<td>ipsum</td>
<td>dolor</td>
<td>sit</td>
</tr>
<tr>
<td>1,002</td>
<td>amet</td>
<td>consectetur</td>
<td>adipiscing</td>
<td>elit</td>
</tr>
</tbody>
</table>
</div>
The sticky header worked until I wrapped the table in the div.table-responsive
. How do I allow these to co-exist?
Upvotes: 8
Views: 6610
Reputation: 9517
In this case you need to code it yourself. Following JS will do the job:
var element = document.getElementById("fixed-thead");
var parentElement = element.parentElement;
window.addEventListener('scroll', () => {
var coordinates = parentElement.getBoundingClientRect();
if (coordinates.y < 0) {
element.style.transform = 'translate3d(0, ' + (-coordinates.y) + 'px, 0)';
} else {
element.style.transform = 'translate3d(0,0,0)';
}
});
And in your table mark thead
with id="fixed-thead"
like this:
<thead id="fixed-thead">
I use translate3d
to enable hardware acceleration to make it smoother. If user uses wheel to scroll scroll event is triggering very ofter I recommend using debouncing of scroll events.
In case your table has column with fixed with you can use setting position: fixed
and top: 0
instead of translate3d
. But in case of a variable length translate3d
is preferred.
In case you need to apply this code to multiple pages on page use following code:
function applyFixedHeader(element) {
var parentElement = element.parentElement;
window.addEventListener('scroll', () => {
var coordinates = parentElement.getBoundingClientRect();
if (coordinates.y < 0) {
element.style.transform = 'translate3d(0, ' + (-coordinates.y) + 'px, 0)';
} else {
element.style.transform = 'translate3d(0,0,0)';
}
});
}
var elements = document.querySelectorAll("{yourSelector, e.g. `.table-fixed` for the tables containing class `table-fixed`}");
elements.forEach(element => applyFixedHeader(element));
Upvotes: 6
Reputation: 21411
without any additionnal CSS, you can fix table head by removing table-responsive from the div and adding class="bg-white sticky-top border-bottom" class to table tag. Like this
<div class="table">
<table class="table">
<thead>
<tr>
<th class="bg-white sticky-top border-bottom">FirstName</th>
<th class="bg-white sticky-top border-bottom">LastName</th>
<th class="bg-white sticky-top border-bottom">Class</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Cooker</td>
<td>A1</td>
</tr>
<tr>
<td>David</td>
<td>Jeferson</td>
<td>A2</td>
</tr>
...
</table>
</div>
Upvotes: 3
Reputation: 18891
There's no way to co-exist a position: sticky
inside a .table-responsive
without re-implementing the latter.
My solution ended up to be using .table-responsive-sm
to refuse this trade-off when a responsive table is certainly not needed.
Upvotes: 10