I've been searching over the web for the way to make a table with fixed (frozen) columns and header. Seems like I finally found the solution and modified it to my needs.
There original fiddle is here.
Here is my modified solution. I tested it in Chrome (version: 55.0.2883.87 m) and Firefox (version: 51.0.1).
The problem is that it works not completely in IE (version: 11.0.9600.18427). During the horizontal scrolling a frozen part of the header is getting scrolled too. Could someone help me to make it working in IE? And one more question: is the approach safe to use? I mean if it's using some unspecified behavior, then some of the future browsers or even some of the modern browsers might display my table in a wrong way, and it's better to use a safe solution with a few different tables and synchronizing scroll position and rows height. UPD: one more question: how to make this work stable on the mobile devices?
Here is some code that demonstrates the approach:
$(document).ready(function() {
$('tbody').scroll(function(e) { //detect a scroll event on the tbody
/*
Setting the thead left value to the negative valule of tbody.scrollLeft will make it track the movement
of the tbody element. Setting an elements left value to that of the tbody.scrollLeft left makes it maintain it's relative position at the left of the table.
*/
$('thead').css("left", -$("tbody").scrollLeft()); //fix the thead relative to the body scrolling
$('thead th:nth-child(1)').css("left", $("tbody").scrollLeft()); //fix the first cell of the header
$('tbody td:nth-child(1)').css("left", $("tbody").scrollLeft()); //fix the first column of tdbody
});
});
.container {
height:200px;
width:400px;
overflow: hidden;
}
table {
position: relative;
background-color: #aaa;
border-collapse: collapse;
table-layout: fixed;
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}
/*thead*/
thead {
position: relative;
display: block; /*seperates the header from the body allowing it to be positioned*/
}
thead th {
background-color: #99a;
min-width: 120px;
border: 1px solid #222;
}
thead th:nth-child(1) {/*first cell in the header*/
position: relative;
background-color: #88b;
}
/*tbody*/
tbody {
flex: 1;
position: relative;
display: block; /*seperates the tbody from the header*/
overflow: auto;
}
tbody td {
background-color: #bbc;
min-width: 120px;
border: 1px solid #222;
}
tbody tr td:nth-child(1) { /*the first cell in each tr*/
position: relative;
background-color: #99a;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="container">
<table>
<thead>
<tr>
<th>Name<br/>123</th>
<th>Town</th>
<th>County</th>
<th>Age</th>
<th>Profession</th>
<th>Anual Income</th>
<th>Matital Status</th>
<th>Children</th>
</tr>
<tr>
<th>Name</th>
<th>Town</th>
<th>County</th>
<th>Age<br/>123<br/>321</th>
<th>Profession</th>
<th>Anual Income</th>
<th>Matital Status</th>
<th>Children</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Smith</td>
<td>Macelsfield</td>
<td>Cheshire<br/>123</td>
<td>52</td>
<td>Brewer</td>
<td>£47,000</td>
<td>Married</td>
<td>2</td>
</tr>
<tr>
<td>Jenny Jones<br/>123<br/>312</td>
<td>Threlkeld</td>
<td>Cumbria</td>
<td>34</td>
<td>Shepherdess</td>
<td>£28,000</td>
<td>Single</td>
<td>0</td>
</tr>
<tr>
<td>Peter Frampton</td>
<td>Avebury</td>
<td>Wiltshire</td>
<td>57</td>
<td>Musician</td>
<td>£124,000</td>
<td>Married</td>
<td>4</td>
</tr>
<tr>
<td>Simon King</td>
<td>Malvern</td>
<td>Worchestershire</td>
<td>48</td>
<td>Naturalist</td>
<td>£65,000</td>
<td>Married</td>
<td>2</td>
</tr>
<tr>
<td>Lucy Diamond</td>
<td>St Albans</td>
<td>Hertfordshire</td>
<td>67</td>
<td>Pharmasist</td>
<td>Retired</td>
<td>Married</td>
<td>3</td>
</tr>
<tr>
<td>Austin Stevenson</td>
<td>Edinburgh</td>
<td>Lothian </td>
<td>36</td>
<td>Vigilante</td>
<td>£86,000</td>
<td>Single</td>
<td>Unknown</td>
</tr>
<tr>
<td>Wilma Rubble</td>
<td>Bedford</td>
<td>Bedfordshire</td>
<td>43</td>
<td>Housewife</td>
<td>N/A</td>
<td>Married</td>
<td>1</td>
</tr>
<tr>
<td>Kat Dibble</td>
<td>Manhattan</td>
<td>New York</td>
<td>55</td>
<td>Policewoman</td>
<td>$36,000</td>
<td>Single</td>
<td>1</td>
</tr>
<tr>
<td>Henry Bolingbroke</td>
<td>Bolingbroke</td>
<td>Lincolnshire</td>
<td>45</td>
<td>Landowner</td>
<td>Lots</td>
<td>Married</td>
<td>6</td>
</tr>
<tr>
<td>Alan Brisingamen</td>
<td>Alderley</td>
<td>Cheshire</td>
<td>352</td>
<td>Arcanist</td>
<td>A pile of gems</td>
<td>Single</td>
<td>0</td>
</tr>
</tbody>
</table>
</div>
</body>