I've had really good luck applying a css transform on scroll in order to have a fixed table header. But now I would like to try the same technique when scrolling horizontally to have pinned columns.
The problem I'm running into is that the pinned columns in the header appear behind instead of on top when scrolling horizontally. The browser is deciding which DOM elements should be on top after doing the transformation. Anything I can do to control this? (yes, I've tried z-index)
Demo
(function() {
var app = angular.module("soDemo", []);
app.controller("soDemoController", SoDemoController);
SoDemoController.$inject = ['$scope', '$document'];
function SoDemoController($scope, $document) {
var vm = {
data: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
};
$scope.vm = vm;
$('.table-container').on('scroll', onScroll);
return;
/////////// IMPLEMENATION ////////
function onScroll() {
var translate = "translate(0," + this.scrollTop + "px)";
$("table thead th:not(.pinned)").css('transform', translate);
translate = "translate(" + this.scrollLeft + "px,0)";
$("table tbody .pinned").css('transform', translate);
translate = "translate(" + this.scrollLeft + "px," + this.scrollTop + "px)";
$("table thead th.pinned").css('transform', translate);
}
}
})();
.table-container {
overflow: auto;
height: 200px;
width: 300px
}
table {
table-layout: fixed;
border-spacing: 0;
}
td {
padding: 3px;
white-space: nowrap;
border-right: 1px solid #ccc;
}
th {
background: #999;
}
th.pinned {
background: #ccc;
}
td.pinned {
background: #eee;
}
input {
margin-top: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<div class="sample" ng-app="soDemo" ng-controller="soDemoController">
<p>When you scroll horizontally, the header row scrolls on top of col0 and col1 instead of behind it.</p>
<p>When you scroll vertically, the tbody cells render over top of Col 0 and Col 1 headers instead of behind it</p>
<div class="table-container">
<table>
<thead>
<tr>
<th class="pinned">Col 0</th>
<th class="pinned">Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
<th>Col 5</th>
<th>Col 6</th>
<th>Col 7</th>
<th>Col 8</th>
<th>Col 9</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in vm.data">
<td class="pinned">Data {{item}}</td>
<td class="pinned">Data {{item}}</td>
<td>Data {{item}}</td>
<td>Data {{item}}</td>
<td>Data {{item}}</td>
<td>Data {{item}}</td>
<td>Data {{item}}</td>
<td>Data {{item}}</td>
<td>Data {{item}}</td>
<td>Data {{item}}</td>
</tr>
</tbody>
</table>
</div>
</div>