Getting the height of a table row

18,402

Solution 1

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

Solution 2

document.getElementById('your_row_id').offsetHeight;

Solution 3

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.

Solution 4

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>

Solution 5

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>
Share:
18,402
user495688
Author by

user495688

Updated on July 26, 2022

Comments

  • user495688
    user495688 almost 2 years

    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>
    
  • user495688
    user495688 over 13 years
    whether offsetheight also applies to determine the row height of a paragraph?
  • G. Allen Morris III
    G. Allen Morris III over 9 years
    You need to know the 'border-spacing' as well.
  • Ankit
    Ankit over 4 years
    Learned something new, could you explain getComputedStyle(elemnt, null) a little, (what is null doing)
  • Gosi
    Gosi over 4 years
    @Ankit The null is actually a pseudoElement. In this case we have none, so I've set is as null. I studied this at w3schools.com/jsref/jsref_getcomputedstyle.asp . You can use this as a reference. Its an optional option.
  • Brad
    Brad over 4 years
    This doesn't actually answer the question, as it doesn't factor in border spacing. It's also dangerous to make an assumption that the measurements are always going to be in pixels.
  • Brad
    Brad over 4 years
    This is probably the closest answer so far. The only thing is that it won't guarantee any particular row... just the average height of all of them. This may not matter if all of the rows are the same height.
  • Gosi
    Gosi over 4 years
    @Brad window.getComputedStyle(elmnt, null).getPropertyValue('padding-top'); var paddedHe will always return the value in pixels. Even if the padding is in % it will get the pixel value of it. Try changing the css padding value to 5% and you can see it.
  • Brad
    Brad over 4 years
    @Gosi Interesting, did not know that! Thanks for the information.
  • Gosi
    Gosi over 4 years
    @Brad I've added calculations for border-space and updated the answer. Now, we can take total height to minus off the padding, margins and border-space.
  • vinothvs
    vinothvs over 4 years
    And also there is a possibilities that it may overflow beyond height, isn't it not the case? Then how can we calculate based on no of rows?
  • Aftershock
    Aftershock over 2 years
    this is most accurate ... but it was 1 pixel more than in reality.