Bug Tracker

Ticket #1818: jQueryBug.html

File jQueryBug.html, 4.2 kB (added by BryceLohr, 1 year ago)

Demonstrates incorrect width() results

Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html lang="en">
3<head>
4    <title>jQuery width() Bug</title>
5    <style type="text/css">
6        #div1 {
7            position: absolute;
8            border: 1px dashed black;
9            padding: 10px;
10        }
11        #div2 {
12            position: absolute;
13            border: 1px dashed black;
14            padding: 10px;
15        }
16        #div3 {
17            width: 200px;
18            position: absolute;
19            border: 1px dashed black;
20            padding: 10px;
21        }
22        #div4 {
23            width: 200px;
24            position: absolute;
25            border: 1px dashed black;
26            padding: 10px;
27        }
28    </style>
29    <script type="text/javascript" src="js/jquery-nightly.js"></script>
30    <script type="text/javascript">
31        $(function() {
32            $("#div2").hide();
33            $("#div1w").text( $("#div1").width() );
34            $("#div2w").text( $("#div2").width() );
35
36            $("#showBtn").click(function(evt) {
37                $("#div1").toggle(); // get div1 out of the way
38                $("#div2").toggle();
39                $("#div2w").text( $("#div2").width() );
40            });
41
42            $("#div4").hide();
43            $("#div3w").text( $("#div3").width() );
44            $("#div4w").text( $("#div4").width() );
45
46            $("#showBtn2").click(function(evt) {
47                $("#div3").toggle(); // get div3 out of the way
48                $("#div4").toggle();
49                $("#div4w").text( $("#div4").width() );
50            });
51        });
52    </script>
53</head>
54
55<body>
56    <h1>width() Bug</h1>
57    <p>jQuery's width() method returns an incorrect value when used on an invisible element with
58    absolute or fixed positioning. However, this is only the case when the invisible element does
59    not have an explicitly assigned width. This can be traced to the css() method: in its "width"
60    case for invisible elements, it clones the node and sets the padding/border widths to zero to
61    measure the element. The problem is that it also explicitly sets the "left" and "right" edge
62    positions, which will implicitly change the element's width when it has no explicit width. That
63    code appears to be intended to position the element at the origin point of the page, but due to
64    a simple oversight actually ends up changing the element size. This behaviour is consistently
65    incorrect on Firefox 2, IE 7, and Opera 9 (all on Windows; I don't have access to a Mac).</p>
66
67    <p>The work-around, is of course, to display the element before trying to get its size. However,
68    you shouldn't have to do this, and usually you want to position the element before displaying
69    it. Changing the positioning to something else is no good, since that completely changes how
70    the browser sizes the element.</p>
71
72    <p>This demonstrates the bug. Watch the #div2/#div4 width values as you click the buttons.</p>
73
74
75    <h2>Div's without explicit widths</h2>
76    <table>
77        <tr><th>Div id</th><th>Result of width()</th></tr>
78        <tr><td>div1</td><td id="div1w"></td></tr>
79        <tr><td>div2</td><td id="div2w"></td></tr>
80    </table>
81
82    <input type="button" id="showBtn" value="Toggle #div2">
83
84    <div id="div1">
85        This is div #div1
86    </div>
87    <div id="div2">
88        Div #div2 lies here
89    </div>
90
91
92    <h2 style="margin-top: 3em">Div's with explicit widths</h2>
93    <table>
94        <tr><th>Div id</th><th>Result of width()</th></tr>
95        <tr><td>div3</td><td id="div3w"></td></tr>
96        <tr><td>div4</td><td id="div4w"></td></tr>
97    </table>
98
99    <input type="button" id="showBtn2" value="Toggle #div4">
100
101    <div id="div3">
102        This is div #div3
103    </div>
104    <div id="div4">
105        Div #div4 lies here
106    </div>
107
108
109    <h2 style="margin-top: 3em">The Fix</h2>
110    <p>The bug has an easy, one-line fix:</p>
111
112    <strong>From: <a href="http://dev.jquery.com/browser/trunk/jquery/src/core.js?rev=3669#L773">src/core.js@3669, line 773</a></strong>
113    <pre>right: "0",</pre>
114
115    <strong>To:</strong>
116    <pre>top: "0",</pre>
117</body>
118</html>