Reputation: 3426
Here is the infamous table:
My boss wants me, at this time of the year, to make the header of the table fixed, so the user can scroll down the table and continue reading the header. I want to preserve the original precomputed dimensions of the table, I mean, the width that every column has at the moment of its creation (widths aren't established by CSS) and then, adapt the header so its columns match the columns of the body. Following some of the answers I found in Stackoverflow, I started making the header and the body of the table display: block
. And after that, I wrote this:
function setTableHeadDimensions() {
var $taskTable = $('.tablaTareas_PEMVISUALIZA'),
$firstRow = $taskTable.find('tbody > tr:first-child'),
$firstRowTds = $firstRow.find('td'),
$firstRowHead = $taskTable.find('thead > tr:first-child'),
$secondRowHead = $taskTable.find('thead > tr:eq(1)'),
$firstRowHeadThs = $firstRowHead.find('th'),
$secondRowHeadThs = $secondRowHead.find('th'),
i = 0,
cells = [];
//We prepare CSS, so we can specify width.
$taskTable
.css('table-layout', 'fixed')
.find('td, th').each(function () {
var $tdh = $(this);
$tdh.css('box-sizing', 'border-box');
$tdh.css('overflow', 'hidden');
});
//Cells of the first row of the table head.
for (i = 0; i < 3; i++) {
cells.push($($firstRowHeadThs[i]));
}
//Cells of the second row of the table head.
for (i = 0; i < $secondRowHeadThs.length; i++) {
cells.push($($secondRowHeadThs[i]));
}
//Rest of the cells for the first row.
for (i = 5; i < $firstRowHeadThs.length; i++) {
cells.push($($firstRowHeadThs[i]));
}
//Try to set the width of the current column's header cell
//to the biggest cell width in the column.
for (i = 0; i < cells.length; i++) {
var maxWidth = 0;
$taskTable.find('td:nth-child(' + (i + 1) + ')').each(function () {
var $el = $(this);
maxWidth = Math.max(maxWidth, $el.width());
});
cells[i].width(maxWidth);
}
}
But, as you can see in the picture, the browser doesn't want to cooperate. What's more, it establishes the width of the cell, but to a number that doesn't match the width of it's corresponding column:
What's more, it doesn't match the width of the row it should match:
So I have two questions:
Here's a codepen with the example cut down to the minimum necessary: Codepen example
Upvotes: 4
Views: 1926
Reputation: 3426
I solved it. In reality, there were two problems:
The first one is that jQuery.width()
returns only the width of the content of the cell, without padding and margin (even if you specify border-sizing: border-box
). I found more natural to use jQuery.css('width')
and then take borders and padding into account in my calculations, without specifying border-sizing: border-box
because retrieving the width with border-sizing: border-box
and then setting it in another element with the idea of matching both widths can be error prone (I had problems with it).
The second one is if you use rowspan
in the header of the table. In that case, you have to establish the width of the rows envolved doing the proper calculations, not only one of them hopping that the rest of the rows will adapt.
Here's the codepen with the solution: http://codepen.io/PolarKuma/pen/BQXMbO
Upvotes: 2