The entire code required to answer your question is too large to include here. Instead, I'll link you to the JSBin which holds the answer, and just include the styling and javascript.
The caveats are:
- If you are dead set on using tables instead of divs to display your data, then you're going to have a bad time formatting the answer I gave you, especially if the data in the cells are varying widths and heights.
- In order to accomplish this, you must go through each row and column header, then set their respective widths and heights to the max between their widths/heights and the widths/height of the rows in the table. The reason why their widths and heights aren't automatically set respective to the rest of the cells in the table is because upon setting their
position: fixed
style attribute, you basically break them out of the table.
- So, if you have the power, consider using divs instead and breaking the row headers out into a separate
div
you can position: fixed
and emulate the current behavior of the column headers.
- Another bonus is that you will have a performance increase because jQuery will not be iterating through every row to adjust the row headers every time you scroll.
- You must use jQuery UI.
HTML:
<!-- Notice I removed background and border color from table tag -->
<table border="0" width="100%" cellpadding="3" cellspacing="1">
<tr>
<td>Dead Cell</td><!-- this cell is not shown -->
...
CSS:
/* Make white space above table since we broke the column headers out of the table */
table {
margin-top: 51px;
position: relative;
}
table td {
border: 1px solid #FFCC00;
height: 44px;
background-color: #FFFFCC;
}
/* styling for column headers */
table tr:first-child {
position: fixed;
top: 0;
left: 57px;
z-index: 100;
}
/* remove first cell in top left position */
table tr:first-child td:first-child {
display: none;
}
table tr:first-child td,
table tr {
position: relative;
}
table tr:first-child td {
background: orange;
}
table tr td:first-child {
background: orange;
position: fixed;
width: 39px
}
/* Make white space to the left of table since we broke the row headers out of the table */
table tr:nth-child(n+2) td:nth-child(2) {
margin-left: 48px;
display: block;
}
JS:
$(function(){ // When document is loaded and ready
$(window).scroll(function() { // When we scroll in the window
// Move column headers into place
$('table tr:first-child td').css('left', - $(this).scrollLeft());
// Move row headers into place
$('table tr td:first-child').each(function() {
$(this).position({ // jQuery UI overloaded function
my: "left top",
at: "left top",
of: $(this).parent(),
using: function(pos) {
$(this).css('top', pos.top);
}
});
});
});
});
Again, here is the link to the JSBin.