I noticed something odd yesterday—or at least something I didn't expect. When I call offsetParent() on an element with position: fixed, I get back a reference to the body tag rather than the nearest positioned element in the DOM. Is this expected behavior? If so, why? I'd appreciate if someone could explain to me.
I am including some sample code that will illustrate what I'm talking about: a relatively positioned div with one absolutely positioned and one fixed positioned child. Load the example in a browser that supports window.console and you'll see log statements showing the result of a call to offsetParent() for each. I would expect both the absolute and fixed position divs to return the relatively positioned one as their offset parents, but offsetParent says the fixed position div's offset parent is the body element.
I saw this behavior with both jquery 1.3.2 and 1.4, and in Safari 4.0.4 (6531.21.10) and Firefox 3.5.7 on a Mac running OS X 10.6.2.
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <!-- meta tags --> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <style type="text/css"> body { margin: 0px; padding: 0px; } #main { position: relative; margin: 50px; padding: 25px; width: 596px; height: 200px; border: 2px solid #c0c0c0; font-size: 12px; text-align: center; line-height: 200px; } #absolute { position: absolute; top: 25px; left: 25px; padding: 10px; width: 126px; border: 2px solid #c0a058; line-height: 18px; } #fixed { position: fixed; top: 77px; left: 523px; width: 126px; padding: 10px; border: 2px solid #80afaf; line-height: 18px; } </style> <!-- external javascript links --> <!-- libraries --> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"> </script> <!-- page-specific utilities --> <script type="text/javascript"> (function($) { $(function() { if(window.console) { var main = $("#main"); var abs = $("#absolute"); var fixed = $("#fixed"); window.console.log("#main:"); window.console.log("\toffsetParent: " + main.offsetParent().attr("id")); window.console.log("#absolute:"); window.console.log("\toffsetParent: " + abs.offsetParent().attr("id")); window.console.log("#fixed:"); window.console.log("\toffsetParent: " + fixed.offsetParent().attr("id")); } }); })(jQuery); </script> <title>jQuery Fixed Position Test</title> </head> <body id="fixed-position-test"> <div id="main"> <div id="absolute"> absolute </div> <!-- /absolute --> <div id="fixed"> fixed </div> <!-- /fixed --> relative </div> <!-- /main --> </body> </html>