The problem I'm facing is the following. I've written a JavaScript function to make a scrollable table. The reason I use JavaScript is to spare me of the cross browser compatibility issues I'd have with CSS. Since the number of table-rows are quite limited, a maximum of 40 rows, the overhead of using JavaScript seems to be no issue. The code is shown here:
function correctTableHeaderSize(){
var count = 0;
var sizes = [];
$("#table").find("th").each(function(){
sizes[count] = $(this)[0].clientWidth;
count++;
});
$("#table").find("tbody").children("tr").each(function(){
counter=0;
$(this).children("td").each(function(){
if($(this).next().is("td")){
$(this).css('width',sizes[counter]);
counter++;
}
});
});
$("#table").prop("hidden",false);
}
What it does:
- Get the width of all table headers (of table with id "table") and store these in an array
- for all rows in the table body, get the child cells and set there width to match the width of their corresponding table header.
This worked fine until I noticed an annoying fact, that is starting to turn in to a serious problem. The table headers and the corresponding cells underneath are not the same size. They differ a few pixels. The wider the header gets, the greater this difference is.
Using Firebug I noticed for example that a th element with a width of 30%, defined with inline css was translated to a scroll-width of 406px, this was also the value I've found in the array containing these widths, but after the JavaScript function finished the scroll-width of the corresponding table cells were 419px, while the css applied to this element shows a width of 406px. Somewhere, somehow 13px were added, although margin and padding for th and td are set to 0. The reason I checked the scroll-width is based on this topic explaining all sorts of width properties, this way I'm sure I take the total sizes into account. See the snippet for an example of the code.
function correctTableColumns() {
var count = 0;
var sizes = [];
$("#table").find("th").each(function() {
sizes[count] = $(this)[0].clientWidth;
count++;
});
$("#table").find("tbody").children("tr").each(function() {
counter = 0;
$(this).children("td").each(function() {
if ($(this).next().is("td")) { //this to let the last cell take al available space, this way the scrollbar width is not an issue
$(this).css('width', sizes[counter]);
counter++;
}
});
});
$("#table").prop("hidden", false);
}
table.scrollTable {
width: 100%;
}
table.scrollTable thead,
table.scrollTable tbody {
float: left;
width: 100%;
}
table.scrollTable tbody {
overflow-y: scroll;
height: 50px;
width: 100%;
}
table.scrollTable th {
white-space: normal;
margin: 0px;
padding: 0px;
}
table.scrollTable td {
margin: 0px;
padding: 0px;
}
table.scrollTable tr {
width: 100%;
display: table;
}
table.scrollTable thead {
overflow: false;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
<table id="table" class="scrollTable" bgcolor="#94BAE7">
<THEAD>
<TR width=\ "100%\">
<TH bgcolor="#CCFF99" width="8%">Col1</TH>
<TH bgcolor="#FFA347" width="8%">Col2</TH>
<TH bgcolor="#CCFF99" width="30%">Col3</TH>
<TH bgcolor="#FFA347" width="2%">Col4</TH>
<TH bgcolor="#CCFF99" width="8%">Col5</TH>
<TH bgcolor="#FFA347" width="8%">Col6</TH>
<TH bgcolor="#CCFF99" width="2%">Col7</TH>
<TH bgcolor="#FFA347" width="30%">Col8</TH>
<TH bgcolor="#CCFF99" width="3%">Col9</TH>
<TH></TH>
</TR>
</THEAD>
<TBODY>
<tr>
<td bgcolor="#CCFF99">10</td>
<td bgcolor="#FFA347">10</td>
<td bgcolor="#CCFF99">I am short</td>
<td bgcolor="#FFA347">100</td>
<td bgcolor="#CCFF99">100</td>
<td bgcolor="#FFA347">100</td>
<td bgcolor="#CCFF99">100</td>
<td bgcolor="#FFA347">10</td>
<td bgcolor="#CCFF99">foo</td>
</tr>
<tr>
<td bgcolor="#CCFF99">10</td>
<td bgcolor="#FFA347">10</td>
<td bgcolor="#CCFF99">I am a longer sentence</td>
<td bgcolor="#FFA347">100</td>
<td bgcolor="#CCFF99">100</td>
<td bgcolor="#FFA347">100</td>
<td bgcolor="#CCFF99">100</td>
<td bgcolor="#FFA347">10</td>
<td bgcolor="#CCFF99">foo</td>
</tr>
</TBODY>
</table>
<input type="button" value="Repair this table" onclick="correctTableColumns();">
</body>
</html>
Does anyone have an idea how this small difference in widths is possible?
Solution
The problem was indeed the width of one the columns but the source of this issue was not the text that was too long but rather a hidden td at the end of each tr. this contained an image that is shown if a certain condition is met.
This hidden td should've taken up the remaining space in the tr, but since it was hidden, it took no space at all. The remaining space was then filled up by the other td's which all got a piece of the remaining space. Therefore the small size-difference on each td. By making the image and not the parent td hidden this issue was solved.
Since the comment of Raidri fixed the issue in the snippet and put me on the right track I've upvoted his answer (but I do not have sufficient rights to do this, I'm sorry). Thank you