views:

282

answers:

3

Im perplexed by this one.

jQuery.height() is coming back with different values in Firefox and Chrome. Measuring the pixels on-screen indicates that of the two, Chrome appears to be reporting the correct value, while firefox is off by 2 or 3 pixels each time. Has anyone else encountered this issue?

I've tried grabbing the height using the various jQuery height functions (innerHeight, outerHeight, height) to no avail. I have stripped all css styling that may have potentially been interfering with the height value (all padding, borders, margin, etc) yet I still get inconsistent results.

If it helps, I am dealing with table cells. The code creates a second table alongside the first, and then matches the height of each row to create a sort of "sticky" left hand column on the table. The cells have varying content but matching 0 values for border, padding and margin on all sides.

EDIT 6 hours later, this problem continues to stump me.

When I nix the borders and switch to using innerHeight() to get the height measurement, both browsers render it perfectly. But I need to get a bottom-border in there...

At the moment I have webkit rendering the table with the borders perfectly, and firefox is off by 1px on each cell. I switched to using jQuery's innerHeight() function to grab the heights of the cells on the 'master' table, but somehow firefox always comes up a pixel short on the measurement.

Here is the relevant code involved. Note that the HTML is copied from firebug AFTER being generated by the javascript, so the height declarations are being made there. 'master' table HTML:

<table cellpadding="0" border="0" class="items-table">
<tbody>
    <tr class="selected">
        <td itemid="70609" class="id" style="display: none;">
            70609
        </td>
        <td class="thumb">
            <div class="item-thumb">
                <div style="background-image: url(&quot;http://c1263382.cdn.cloudfiles.rackspacecloud.com/2C5D13C6-8A9F-47D9-81B51305D3FF24A9_t.jpg&amp;quot;);" class="item-thumb-image">
                    <img src="http://c1263382.cdn.cloudfiles.rackspacecloud.com/2C5D13C6-8A9F-47D9-81B51305D3FF24A9_t.jpg"&gt;
                </div>
            </div>
        </td>
        <td class="details">
            <div class="name">
                <span class="code">R1000</span> <span class="description">Armoire</span>
            </div>
            <div class="itemtype">
                <span>Casegoods</span> <input type="hidden" value="13" name="70609-itemtypeid" id="70609-itemtypeid" class="itemtypeid">
            </div>
        </td>
    </tr>
    <tr class="selected">
        <td itemid="70634" class="id" style="display: none;">
            70634
        </td>
        <td class="thumb">
            <div class="item-thumb">
                <div style="background-image: url(&quot;http://c1263382.cdn.cloudfiles.rackspacecloud.com/29DA825A-0431-49ED-A2614B3544EB50D2_t.jpg&amp;quot;);" class="item-thumb-image">
                    <img src="http://c1263382.cdn.cloudfiles.rackspacecloud.com/29DA825A-0431-49ED-A2614B3544EB50D2_t.jpg"&gt;
                </div>
            </div>
        </td>
        <td class="details">
            <div class="name">
                <span class="code">C1124</span> <span class="description">Nightstand</span>
            </div>
            <div class="itemtype">
                <span>Casegoods</span> <input type="hidden" value="13" name="70634-itemtypeid" id="70634-itemtypeid" class="itemtypeid">
            </div>
        </td>
    </tr>
    <tr class="selected">
        <td itemid="70642" class="id" style="display: none;">
            70642
        </td>
        <td class="thumb">
            <div class="item-thumb">
                <div style="background-image: url(&quot;http://c1263382.cdn.cloudfiles.rackspacecloud.com/46AAB8C6-7BAD-4740-8B26A05521025029_t.jpg&amp;quot;);" class="item-thumb-image">
                    <img src="http://c1263382.cdn.cloudfiles.rackspacecloud.com/46AAB8C6-7BAD-4740-8B26A05521025029_t.jpg"&gt;
                </div>
            </div>
        </td>
        <td class="details">
            <div class="name">
                <span class="code">999</span> <span class="description">Nice Table New Name</span>
            </div>
            <div class="itemtype">
                <span>Casegoods</span> <input type="hidden" value="13" name="70642-itemtypeid" id="70642-itemtypeid" class="itemtypeid">
            </div>
        </td>
    </tr>
    <tr class="selected">
        <td itemid="70643" class="id" style="display: none;">
            70643
        </td>
        <td class="thumb">
            <div class="item-thumb">
                <div style="background-image: url(&quot;http://c1263382.cdn.cloudfiles.rackspacecloud.com/71F27D5A-8BA6-428B-BAD842D699B6591A_t.jpg&amp;quot;);" class="item-thumb-image">
                    <img src="http://c1263382.cdn.cloudfiles.rackspacecloud.com/71F27D5A-8BA6-428B-BAD842D699B6591A_t.jpg"&gt;
                </div>
            </div>
        </td>
        <td class="details">
            <div class="name">
                <span class="code">OC603</span> <span class="description">Coffee Table</span>
            </div>
            <div class="itemtype">
                <span>Casegoods</span> <input type="hidden" value="13" name="70643-itemtypeid" id="70643-itemtypeid" class="itemtypeid">
            </div>
        </td>
    </tr>
    <tr class="">
        <td itemid="70644" class="id" style="display: none;">
            70644
        </td>
        <td class="thumb">
            <div class="item-thumb">
                <div style="background-image: url(&quot;http://c1263382.cdn.cloudfiles.rackspacecloud.com/BB263083-013F-4188-BF26CA77CF66C1E5_t.jpg&amp;quot;);" class="item-thumb-image">
                    <img src="http://c1263382.cdn.cloudfiles.rackspacecloud.com/BB263083-013F-4188-BF26CA77CF66C1E5_t.jpg"&gt;
                </div>
            </div>
        </td>
        <td class="details">
            <div class="name">
                <span class="code">OC606</span> <span class="description">Coffee Table</span>
            </div>
            <div class="itemtype">
                <span>Casegoods</span> <input type="hidden" value="13" name="70644-itemtypeid" id="70644-itemtypeid" class="itemtypeid">
            </div>
        </td>
    </tr>
</tbody>

secondary table HTML:

<table cellpadding="0" border="0" class="items-table">
    <tbody>
        <tr>
            <td itemid="70609" class="id" style="height: 45px;"></td>
            <td data-contactid="34759" class="bid pending" style="height: 45px;">
                <div class="bid-container">
                    &nbsp;
                    <div>
                        Sent 2 days ago
                    </div>
                </div>
            </td>
            <td data-contactid="34746" class="bid" style="height: 45px;">
                <div class="bid-container">
                    &nbsp;
                </div>
            </td>
        </tr>
        <tr>
            <td itemid="70634" class="id" style="height: 53px;"></td>
            <td data-contactid="34759" class="bid" style="height: 53px;">
                <div class="bid-container">
                    &nbsp;
                </div>
            </td>
            <td data-contactid="34746" class="bid bid-data assigned" style="height: 53px;">
                <div class="bid-container">
                    &nbsp;
                    <div class="cost">
                        $90.00
                    </div>
                </div>
            </td>
        </tr>
        <tr>
            <td itemid="70642" class="id" style="height: 53px;"></td>
            <td data-contactid="34759" class="bid pending" style="height: 53px;">
                <div class="bid-container">
                    &nbsp;
                    <div>
                        Sent 2 days ago
                    </div>
                </div>
            </td>
            <td data-contactid="34746" class="bid" style="height: 53px;">
                <div class="bid-container">
                    &nbsp;
                </div>
            </td>
        </tr>
        <tr>
            <td itemid="70643" class="id" style="height: 45px;"></td>
            <td data-contactid="34759" class="bid pending" style="height: 45px;">
                <div class="bid-container">
                    &nbsp;
                    <div>
                        Sent 2 days ago
                    </div>
                </div>
            </td>
            <td data-contactid="34746" class="bid" style="height: 45px;">
                <div class="bid-container">
                    &nbsp;
                </div>
            </td>
        </tr>
        <tr>
            <td itemid="70644" class="id" style="height: 45px;"></td>
            <td data-contactid="34759" class="bid" style="height: 45px;">
                <div class="bid-container">
                    &nbsp;
                </div>
            </td>
            <td data-contactid="34746" class="bid" style="height: 45px;">
                <div class="bid-container">
                    &nbsp;
                </div>
            </td>
        </tr>
    </tbody>
</table>

CSS:

.items-table {
    font-size: 12px;
    color: #252629;
    position: relative;
}
.items-table td {
    height: 46px;
    padding: 4px;
    border-bottom: 1px solid #E0E3E3;
    vertical-align: top;
}
.items-table .item-thumb { margin-right: 0px; }

.items-table tr { cursor: pointer; }

.items-table td.id { display:none; }
.items-table td.checkbox { width: 16px; padding: 0 6px 0 9px; vertical-align: middle; }
.items-table td.thumb { width: 48px; vertical-align: middle; }

.items-table td.details { vertical-align: middle; }
.items-table td.details .code { font-weight: bold; }
.items-table td.details .itemtype { color: #606060; }

.items-table tr.selected td {
    background: #E3E3E3;
}
.items-table tr:hover td { background: #ccdbe5; }
.items-table tr.active td { background: #1f6497 url('/images/selected-item.png') repeat-x  top left; color: white; font-weight: bold; }
.items-table tr.active .itemtype { color: #C1C5E1; }

.items-table .cost { padding: 2px 0 0 0; }
.items-table .tags { padding: 2px 0 0 0; }

jQuery business:

$('#items .items-table tr').each(function() {
                        var ti = $(this).find('.id').text();
                        $('#bids .items-table').append("<tr><td class='id' itemid='"+ti+"'></td>"+newCells+"</tr>")
                        var th = $(this).find('td.thumb').innerHeight();
                        $('#bids .items-table').find('tr:last td').height(th);
                    });

And this is what it looks like in Chrome: alt text

Firefox: alt text

+1  A: 

I had the similar problem, that seems to be a bug although i am not 100% sure. If for example, a certain element has padding, the innerHeight() didn't show the same result in Webkit and Firefox. As temporary fix, I used both innerHeight() as well as height() to get the right height for that element.

Similarly, I wasn't able to use the height() to show the same across browsers (IE and others). I used something like this that worked across browsers:

$("#element").css('height', '100');

See also innerHeight() and outerHeight() when you want to include padding / borders / margins.

Sarfraz
thanks sarfraz. you'll see in my js snippet above that i'm using innerHeight(), and also that i mentioned having tried all of jQuery's various height functions with mixed but incorrect results.
DustMason
+6  A: 

Firefox and in general, Gecko based browsers differ from others in that they try to do subpixel layout and rendering.
This can make life hard especially if you work with table cells that are sized based on their contents.
IE, Webkit and Gecko can report different dimensions - the latter reporting some exotic fractional sizes as well.
As for the bug: after struggling with something similar - measuring dimensions of dynamically sized table cells - for a while, I had ended up special casing for fractional numbers.

As it influences positions as well as dimensions, some people ended up using clientWidth instead of jQuery's 'innerWidth()', while some just use parseInt() on the returned results. (Search for fract in the sources.)

If that is not satisfactory, you may try the following:

  • render the primary table with "visibility:hidden" by default so that it is laid out but not displayed
  • measure the cell heights from jQuery
  • round the heights to the nearest integer value in the primary table and apply as an inline style (rounding up may be a good idea to ensure that cells don't cut contents by 1px)
  • render the secondary table based on these integer values and restore visibility of primary table

It might still occur that the borders are misaligned - this can be the case if the position of the primary and secondary tables are not the same (e.g.: primary top: 123.75px, secondary top: 123px.) In that case, placing the tables in a common container or just repositioning to integer coordinates may help.

Good luck...

Edit: As far as I remember, because of some IE and border-collapse anomalies, I resorted to the (deprecated) cellspacing property - that should be placed on the table element into HTML, not CSS - and specified separate borders with a dimension of 0 in CSS. I placed the whole table in a div with a nice background-color.
The whole thing had the effect as if the table borders were 1px, collapsed having the color of the background div....

andras
thanks for your thoughtful answer. however, i went through your suggestions and determined that the issue is not a subpixel layout/rendering one. all browsers seem to be reporting nice round integers for the height values.
DustMason
+4  A: 

Have you tried not styling the TD elements at all, but instead the DIV elements that wrap the cell? Then, calculate and set the DIV heights because that is more reliable? Let the table set the cell height automatically based on its content. This, because you already proved that the different browsers calculate TD heights differently (with border...)

Michael Butler