Reputation: 973
How can I calculate the height of a row (in pixels) in a table with JavaScript?
<table>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
</table>
Upvotes: 9
Views: 25579
Reputation: 5351
if the table can be scrolled.. and the height is needed for scrolling where
<div id="scrolling_chat" style="height:500px;overflow-y:auto;overflow-x: visible;">
<table id = "chat" ></table>
height = $("#scrolling_chat")[0].scrollHeight/document.getElementById("chat").rows.length;
Most accurate as far as I can see...
Upvotes: 0
Reputation: 15120
If you want to get an accurate table row height, then you should use Element.getBoundingClientRect()
rather than Element.offsetHeight
in order to get fractional height rather than a rounded figure.
document.querySelector('tr').getBoundingClientRect().height;
If you also want to include border-spacing
in your calculation of table row height, you need to decide how you want to allocate it to each row (since it is really space between rows and not part of any particular row). Also, be sure to check whether or not the table's border-collapse
property is set to collapse
(if so, then border-spacing
is not included in your table).
In the snippet below, the first / last rows are allocated the space above / below that is not shared with another row, all space between rows is shared evenly. This ensures that the sum of all row heights is equal to the table height.
Alternatively, you could choose not to allocate the space above the first row or below the last row to any row, since this space is not included in the height calculation for <thead>
or <tbody>
elements so that space could be allocated to those elements rather than the rows themselves.
// example log output comments below will change based on browser defaults, zoom, etc
const getRowHeight = (tr) => {
const table = tr.closest('table');
const style = window.getComputedStyle(table);
const collapse = style.getPropertyValue('border-collapse');
const space = parseFloat(
style.getPropertyValue('border-spacing').split(' ')[1].replace(/[^\d.]/g, '')
);
let height = tr.getBoundingClientRect().height;
if (collapse === 'separate') {
if (table.rows.length === 1) {
height += space * 2;
} else if (tr.rowIndex === 0 || tr.rowIndex === table.rows.length - 1) {
height += space + space / 2;
} else {
height += space;
}
}
return height;
};
console.log(getRowHeight(document.querySelector('#single')));
// 24 (20px row height + 2px space above + 2px space below)
console.log(getRowHeight(document.querySelector('#top')));
// 23 (20px row height + 2px space above + 1px space below)
console.log(getRowHeight(document.querySelector('#middle')));
// 22 (20px row height + 1px space above + 1px space below)
console.log(getRowHeight(document.querySelector('#bottom')));
// 23 (20px row height + 1px space above + 2px space below)
<table>
<tr id="single">
<td>Cell</td>
</tr>
</table>
<table>
<tr id="top">
<td>Cell</td>
</tr>
<tr id="middle">
<td>Cell</td>
</tr>
<tr id="bottom">
<td>Cell</td>
</tr>
</table>
Upvotes: 6
Reputation: 103
Sorry Was messed up there a sec
<table>
<tr onclick="alert(this.offsetHeight)">
<td>
Hey
<br /> You
</td>
</tr>
</table>
If you need to get it, you can give the tr an ID and use getElementById().offsetHeight
Upvotes: 0
Reputation: 2003
I've done a few calculations.
padding-top
valuepadding-bottom
valuemargin-top
valuemargin-bottom
valueborder-space
valueNow with all these information, we can take the total heigt and minus off the paddings, margins and border-space.
I've commented in the code on what each line does.
var elmnt = document.getElementsByTagName("td")[0];
var totalHeight = elmnt.offsetHeight; // gets the total height value inclusive of all paddings & margins
// The following is to get the padding-top, padding-bottom, margin-top, margin-bottom values
var paddedHeightTop = window.getComputedStyle(elmnt, null).getPropertyValue('padding-top');
var paddedHeightBottom = window.getComputedStyle(elmnt, null).getPropertyValue('padding-bottom');
var marginHeightTop = window.getComputedStyle(elmnt, null).getPropertyValue('margin-top');
var marginHeightBottom = window.getComputedStyle(elmnt, null).getPropertyValue('margin-bottom');
var borderHeight = window.getComputedStyle(elmnt, null).getPropertyValue('-webkit-border-vertical-spacing');
// To remove the px from the string so we can use it as an integer to subtract from total value.
var newPaddedHeightTop = paddedHeightTop.substring(0, paddedHeightTop.length - 2); // remove the px
var newPaddedHeightBottom = paddedHeightBottom.substring(0, paddedHeightBottom.length - 2); // remove the px
var newMarginHeightTop = marginHeightTop.substring(0, marginHeightTop.length - 2); // remove the px
var newMarginHeightBottom = marginHeightBottom.substring(0, marginHeightBottom.length - 2); // remove the px
var newBorderHeight = borderHeight.substring(0, marginHeightBottom.length - 2); // remove the px
// Take the total and minus of all these paddings, margins and border-space
var finalHeight = totalHeight - newPaddedHeightTop - newPaddedHeightBottom - newMarginHeightTop - newMarginHeightBottom - newBorderHeight;
alert(totalHeight + " (total height) - " + newPaddedHeightTop + " (padding-top) - " + newPaddedHeightBottom + " (padding-bottom) - " + newMarginHeightTop + " (margin-top) - " + newMarginHeightBottom + " (margin-bottom) - " + newBorderHeight + " (border-space) = " + finalHeight);
td {
height: 50px;
padding: 2px;
border-spacing: 2px 3px;
}
<table>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
</table>
<pre></pre>
I've added that css just for you to see that it does minus of all the padding values and gives the exact height of the td
.
Update 1: Added calculations for border-space
.
var borderHeight = window.getComputedStyle(elmnt, null).getPropertyValue('-webkit-border-vertical-spacing');
Also, as explained in the comment, window.getComputedStyle(elmnt, null).getPropertyValue('-webkit-border-vertical-spacing')
gets values in pixels, so even if it is set in percentages, it will retrieve what is its pixel value.
So from this, we can pretty much just get the total value of height and then minus off all the paddings, margins and border-space.
Upvotes: 6
Reputation: 56
var table_elements = document.querySelector("table>tbody");
var i;
for (i = 1; i <= table_elements.rows.length; i++) {
var row_selector = "table>tbody>tr:nth-child(" + [i] + ")";
var table_row = document.querySelector(row_selector);
var vertical_spacing = window.getComputedStyle(table_row).getPropertyValue("-webkit-border-vertical-spacing");
var margin_top = window.getComputedStyle(table_row).getPropertyValue("margin-top");
var margin_bottom = window.getComputedStyle(table_row).getPropertyValue("margin-bottom");
var row_height= parseInt(vertical_spacing, 10)+parseInt(margin_top, 10)+parseInt(margin_bottom, 10)+table_row.offsetHeight
console.log("The height is: "+row_height+"px");
}
<table>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
</table>
You can probably find a better way to loop through the <tr> element.
Gets all the table rows from tbody and loops through all of them using nth-child.
It then sets the row (var row_selector) and obtains its vertical spacing, margin (top and bottom) and the offsetHeight (element height, padding, etc.).
Since offsetHeight only gets the padding, border and scrollbar, but not the margin, we need to get the computed style value like we did with vertical border spacing.
Finally it parses the vertical border spacing and the margin values to an Int and adds it to offsetHeight and logs the final value to the console.
Upvotes: 1
Reputation: 3122
var tableHeight = document.getElementById("tableId").offsetHeight;
var totalRowInTable = document.getElementById("tableId").rows.length;
//So here we have total height of table and total <tr> tags, so tableHeight / total <tr> tag will gave each <tr> tag height.
var trTagHeight = tableHeight/totalRowInTable;
console.log(trTagHeight);
//Note: This is approx value of each row, excluding padding and cell padding value.
<table id="tableId">
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
</tr>
</table>
Upvotes: 4
Reputation: 9489
function findHeights() {
var tbl = document.getElementById('your table').rows;
alert(tbl[0].offsetHeight); // row 1
}
Upvotes: 18