One would think that after the following bit of jQuery, the width of the div selected by #foo would not change at all; after all, we are setting this width to the value it supposedly already has:
var original_width = $('#foo').css('width');
$('#foo').css('width', original_width);
In fact, this reasonable guess appears to be wrong, as shown in this page. I give the code below. The important thing to note is that the four main sections, corresponding to the four .level-0 divs, all have the same structure and content. The second and fourth of them (which have the jqbug class) have their width "re-set" (with a bit of JS, as described above) to the value it supposedly already has. For the second one case, the width is actually changed by this operation; for the fourth case, the width remains unchanged, as expected. The only difference between the definitions of the second and fourth cases is that the former has border-box for its box-sizing parameter.
<div class="level-0 border-box">
<div id="i1" class="level-1">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<div class="level-0 border-box">
<div class="level-1 jqbug">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<div class="level-0">
<div id="i1" class="level-1">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<div class="level-0">
<div class="level-1 jqbug">
<p>Lorem ipsum dolor sit amet</p>
</div>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js">
</script>
(function ($) {
$('.jqbug').each(function () {
$(this).css('width', $(this).css('width'));
});
}(jQuery));
*{
outline:3px solid green;
}
.border-box, .border-box *{
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
.level-0{
position:relative;
margin:10px auto;
width:300px;
height:100px;
font-family:consolas,monaco,courier,monospace;
}
.level-1{
position:absolute;
padding:10px 20px;
background-color:#0aa;
font-size:15px;
}
In this jsFiddle, which uses exactly the same code as shown above, all the divs end up with the same width. On the one hand, this is good: the results have the appearance one would expect. On the other hand, the fact that jsFiddle's result is not representative of what the browser produces directly is just as puzzling as jQuery's behavior.
My questions are:
Is this a bug in jQuery, or is this puzzling behavior somehow in agreement with the CSS spec?
What does one need to do to get the result produced by jsFiddle to look like that produced by the browser?
EDIT: I modified the JS (in both the page linked above and the jsFiddle, as well as in this post) to match that given in Marco Biscaro's answer; this made no difference to the appearance of the page as displayed directly by the browser, but it did affect the appearance of the jsFiddle's result. Now the latter shows no difference in the widths of the various divs. This result still differs from that produced directly by the browser, so the situation is not much better than it was before: we still have that jQuery produces surprising results, and jsFiddle produces results that do not match the browser's results.
$('.jqbug').width()gets the correct value