jQuery bug with offsets, positioning and hidden elements

jQuery bug with offsets, positioning and hidden elements

A strange behavior of jQuery concerning the handling of hidden elements and their offsets.

The jQuery's offset() and position() methods stop working properly on hidden elements. This aspect is not very clear, though it's mentioned in the official documentation. I've noticed that also children elements are affected. But what happens exactly?

If you have the following hypothetical structure:

<body>
	<div id="test">
		<p>...</p>
		<p>...</p>
		<p>...</p>
	</div>
</body>

And the following styles:

#test {
	display: none;
}

One could think that if you make the element visible later with a call to slideDown(), fadeIn() or show(), everything will work as expected. Unfortunately, this is not the case.

If you run a loop through the child elements, the offset() method will always return 0, both for the top and left properties.

Another interesting thing is that even if you use a direct CSS declaration such as display: block to show the hidden element, results will be exactly the same.

As a side note, if you try something like this:

#test {
	position: absolute;
	left: -9999px;
}

And then you reset the above rule with:

$('#test').css('position', 'static');

jQuery will ignore the new display rule and the initial offset of your elements will be calculated by taking -9999 as the initial reference. Odd.