Skip to main content

Bug Tracker

Side navigation

#5520 closed bug (duplicate)

Opened November 17, 2009 08:34AM UTC

Closed December 15, 2011 06:10AM UTC

Last modified August 22, 2012 11:45AM UTC

Incorrect offset values in IE8 under box-sizing: border-box model

Reported by: whale Owned by:
Priority: low Milestone:
Component: dimensions Version: 1.4.4
Keywords: Cc:
Blocked by: Blocking:
Description

When using IE8 in strict mode, but selecting the box-sizing: border-box model (CSS3) for all elements, jQuery reports the offset (Top, Left) values for elements on the page not as relative to the document, but relative to the window.

As soon as a page is scrolled down, incorrect values are reported causing even negative offsets for the offsetParent when elements are scrolled out of view. Under FF 3.5 everything works under both box-sizing models.

See the file attached for a clear demonstration of this bug. When hovering over the input field, the offset + offsetParent offset values are reported of that input field. When scrolling this page down under IE8, incorrect offset values appear.

This bug destroys the correct placement of components like date/time pickers, virtually rendering the box-sizing: border-box model useless, which is a pity.

A fix is greatly appreciated as I would hate to go back to the less convenient box-sizing: content-box model.

Attachments (1)
  • box_model_test6.html (2.1 KB) - added by whale November 17, 2009 08:35AM UTC.

    illustration of the offset bug occurring under IE8 box-sizing: border-box model

Change History (19)

Changed November 17, 2009 01:27PM UTC by snover comment:1

_comment0: I dived into the jQuery source, and solved it myself looking at the code of the offset() routine. The comments below relate to the code there. \ \ In IE8, the self.pageYOffset, body.scrollTop and clientTop vars always remain 0, leaving the box.top variable (which varies with scrolling) as the only var left. In both box-sizing models IE8 has a value for docElem.scrollTop, so there really is no purpose for the boxModel check there. \ \ Just removing the jQuery.boxModel check solves the problem, and now the offset() method returns always correct offset values in both box-sizing models for IE8 & FF. \ \ Now I don't know if that breaks Opera, or older IE versions, but it seems a perfect solution for now. \ \ The core lines of the offset() routine now read: \ \ top = box.top + (self.pageYOffset || docElem.scrollTop || body.scrollTop ) - clientTop, \ left = box.left + (self.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft; \ \ Regards, \ Abraham Guyt.1290306377320671

I dived into the jQuery source, and solved it myself looking at the code of the offset() routine. The comments below relate to the code there.

In IE8, the self.pageYOffset, body.scrollTop and clientTop vars always remain 0, leaving the box.top variable (which varies with scrolling) as the only var left. In both box-sizing models IE8 has a value for docElem.scrollTop, so there really is no purpose for the boxModel check there.

Just removing the jQuery.boxModel check solves the problem, and now the offset() method returns always correct offset values in both box-sizing models for IE8 & FF.

Now I don't know if that breaks Opera, or older IE versions, but it seems a perfect solution for now.

The core lines of the offset() routine now read:

top  = box.top  + (self.pageYOffset || docElem.scrollTop  || body.scrollTop ) - clientTop,
left = box.left + (self.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft;

Regards,

Abraham Guyt.

Changed June 13, 2010 06:36PM UTC by dmethvin comment:2

component: unfileddimensions

Changed November 21, 2010 03:57AM UTC by snover comment:3

milestone: 1.41.4.5
priority: majorlow
status: newopen
version: 1.3.21.4.4

reduced test case. Milestone to 1.4.5 since the user has provided a potential fix.

Changed November 21, 2010 12:51PM UTC by abraham@guyt.org comment:4

It would be nice to have my proposed solution included in an upcoming new jQuery release, as now I have to re-inject my fix manually in every release again to solve this bug. Given the fact it was reported a year ago, that would be too much to ask I guess :-)

Changed July 11, 2011 08:23PM UTC by dmethvin comment:5

milestone: 1.next1.7
owner: → dmethvin
status: openassigned

Changed July 18, 2011 11:56AM UTC by abraham@guyt.org comment:6

Replying to [comment:5 dmethvin]:

yes ... could you please implement the suggested fix in the official release ?

Changed August 15, 2011 12:01AM UTC by whale comment:7

Versions 1.6.2 still contains the mentioned bug for strict IE8, changing the code lines nr 8641 + 8642 to the following solves the problem (just remove the boxmodel check):

scrollTop  = win.pageYOffset || docElem.scrollTop  || body.scrollTop,
scrollLeft = win.pageXOffset || docElem.scrollLeft || body.scrollLeft,

Could it please be included in the 1.7 release ?

Changed August 24, 2011 03:02PM UTC by glenn@gfwebsoft.com comment:8

I need this too ! 1.7 ?

Changed September 28, 2011 05:35PM UTC by dmethvin comment:9

Sorry but I'm just coming up to speed with this patch. The test case appears to have been fixed in jQuery 1.6.2, can you confirm?

Works in 1.6.2: http://jsfiddle.net/ESGnf/9/

Fails in 1.5.2: http://jsfiddle.net/ESGnf/8/

If not, what's the difference between your real-life situation and this test case? Can you create a fiddle where it fails?

This seems to be related to #7986 where our boxModel feature detect is fooled by global css monkey business. I am not sure why we don't use a direct document.compatMode === "BackCompat" there.

Finally, everything still needs to work properly in IE6/7 where box-model is not available but standards/quirks mode exists. How is the patch taking that into account?

Changed September 29, 2011 02:45AM UTC by abraham@guyt.org comment:10

Hi, after testing with your fiddle examples and my code I found what caused the malfunction in the old and existing 1.6.2 code.

Your correct fiddle example has the 1.6.2 jQuery lib include <script> line BEFORE the stylesheet section and results in correct behaviour.

If you move that same lib include <script> line to just AFTER the stylesheet section you're getting the wrong behaviour (with IE8). I can't give you that example with the fiddle interface as it automatically places the lib include line, but if you take the source and move the line manually you'll see the mentioned behaviour.

So somehow the positioning of the jQuery lib inclusion line relative to the stylesheets influences its behaviour in this manner - is this supposed to work like that ?

It's then important devs know it works like that - I wouldn't have found out without your samples - thanks for that.

Changed September 29, 2011 03:00AM UTC by dmethvin comment:11

Oh, that kinda makes sense. The jQuery.support.boxModel (née jQuery.boxModel) variable is calculated during the support tests, and if the page monkeys with the CSS after that it wouldn't affect the calculation. But that doesn't mean the calculation would be right in general.

The way you've changed the value is for all elements, but if someone applied the changes to only certain elements then the assumption that jQuery.support.boxModel makes ("There's only one box model and it applies to all elements and never changes") is wrong. It seems like we'd need to check the element's box-model each time we return the value to be certain we're getting it right.

Changed September 29, 2011 03:08AM UTC by abraham@guyt.org comment:12

It certainly can happen that a single page uses and mixes both border-box models, so it's important the offset values are correct for those cases in IE8 as well. At least we now know the lib inclusion position is crucial to do right :-)

Changed October 10, 2011 12:44AM UTC by AaronAsAChimp comment:13

This is a tricky problem because IE8 supports box-sizing, but has an incorrect default. Previously with the box model test the solution was to set all the properties to the default. Which works because all browsers have the same defaults for padding, border, overflow and display.

It seems the best solution now is to use iframe to create a pristine environment to test against. This fiddle demonstrates it:

http://jsfiddle.net/GESZS/25/

I'm not sure if this will resolve the original issue, but I hope it helps.

Changed October 10, 2011 04:19PM UTC by dmethvin comment:14

milestone: 1.71.8

Moving to 1.8 for a comprehensive solution.

Changed November 10, 2011 04:12AM UTC by dmethvin comment:15

owner: dmethvin
status: assignedopen

Changed December 15, 2011 06:10AM UTC by mikesherov comment:16

resolution: → duplicate
status: openclosed

Changed December 15, 2011 06:10AM UTC by mikesherov comment:17

Duplicate of #7986.

Changed January 30, 2012 03:14PM UTC by dmethvin comment:18

milestone: 1.8

Changed August 22, 2012 11:45AM UTC by odegroot comment:19

Fixed in 1.7.2, along with #7986.