Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the Javascript width of a table cell one pixel too short?

When you apply border-collapse: collapse; to a table to "meld" its cells' borders together, it starts causing problems in determining the widths of table cells in Javascript. For example, look at this page:
http://game-point.net/misc/browserTests/scratchpads/jsTableWidth/
There are two tables, one with collapsed borders and one without. If you click on a row in the one without collapsed borders, jQuery's innerWidth and outerWidth functions report what I would expect to see (the content width, and the content plus the border width respectively; there is no padding).

However, if you click on a row in the table with collapsed borders, you get browser-inconsistent behaviour, especially on the clientWidth property. In Firefox, clientWidth is the same as width(). In IE and Chrome, it's 1 pixel higher, and in Opera, it's the same as width(), but Opera's width() is too small. In fact, the width() is one pixel too small in all the browsers I've tested except for Firefox. So if you take a screenshot and the content is actually 80px, width() is 79px (jQuery gets it from the calculated CSS value). Why is this?

I'm wanting to get the width of the actual content. I can't seem to use width() because only Firefox gets that right with collapsed borders. I can't use outerWidth() because that includes the borders (or maybe just one border, seeing as it's only 1px larger than the actual content width). I can't use clientWidth because its value is inconsistent between browsers. What should I do and why is width() 1px too short in most browsers when borders are collapsed?

like image 398
Jez Avatar asked Nov 08 '12 00:11

Jez


People also ask

How do you increase the width of a table cell?

To adjust column width automatically, click AutoFit Contents. To adjust table width automatically, click AutoFit Window.

How do I resize a table cell in HTML?

To set the cell width and height, use the CSS style. The height and width attribute of the <td> cell isn't supported in HTML5. Use the CSS property width and height to set the width and height of the cell respectively. Just keep in mind, the usage of style attribute overrides any style set globally.

How do I change the width of a TD?

HTML tables can have different sizes for each column, row or the entire table. Use the style attribute with the width or height properties to specify the size of a table, row or column.


1 Answers

In the collapsed border model, cells are not just "melded" they are shared by adjacent cells.

So say you have markup like this:

<table style="border-collapse: collapse">
  <tr>
    <td style="border: 1px solid black; width: 100px">
    <td style="border: 1px solid black; width: 100px">
  </tr>
</table>

In the collapsed border model, the width of this table is 102px. There's 0.5px of border that's actually outside the table, then 0.5px of border, then 100px of cell, then 1px of border, then 100px of cell, then 0.5px of border, then 0.5px of border outside the table. See the picture at http://www.w3.org/TR/CSS21/tables.html#collapsing-borders

So given that, what should a UA return for the various widths of the first cell? Should it be 100px? 101px? 102px? Something else? Simply returning the content width plus the border widths would return 102px, but the actual space taken up by the cell is only 101px...

Furthermore, if jQuery is computing the content width itself it could run into this problem too, if it doesn't special-case border-collapsed cells somehow.

And there is no real spec for clientWidth, much less jQuery's width() and such, of course. That sort of explains why the results you see are all over the place.

As for what you should do, if you actually know exactly what's going on with your borders, you should probably getBoundingClientRect().width (assuming browsers don't mess that up) and subtract off the half-widths of the borders. If you need this to work with various different border widths, I'm not sure there's a great solution.

like image 57
Boris Zbarsky Avatar answered Oct 16 '22 08:10

Boris Zbarsky