user495688
user495688

Reputation: 973

Getting the height of a table row

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

Answers (8)

Aftershock
Aftershock

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

benvc
benvc

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

Malik Tahir
Malik Tahir

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

Gosi
Gosi

Reputation: 2003

I've done a few calculations.

  1. Get the total height value
  2. Get the padding-top value
  3. Get the padding-bottom value
  4. Get the margin-top value
  5. Get the margin-bottom value
  6. Get the border-space value

Now 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

mrbear258
mrbear258

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.

 

Simple code explanation:

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

ankitkanojia
ankitkanojia

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

Jinesh Parekh
Jinesh Parekh

Reputation: 2141

document.getElementById('your_row_id').offsetHeight;

Upvotes: 8

Tim
Tim

Reputation: 9489

function findHeights() {
            var tbl = document.getElementById('your table').rows;
            alert(tbl[0].offsetHeight); // row 1
}

Upvotes: 18

Related Questions