Bug Tracker

Opened 10 years ago

Closed 8 years ago

Last modified 7 years ago

#5520 closed bug (duplicate)

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 10 years ago.
illustration of the offset bug occurring under IE8 box-sizing: border-box model

Download all attachments as: .zip

Change History (20)

Changed 10 years ago by whale

Attachment: box_model_test6.html added

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

comment:1 Changed 10 years ago by whale

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.

Last edited 9 years ago by snover (previous) (diff)

comment:2 Changed 9 years ago by dmethvin

Component: unfileddimensions

comment:3 Changed 9 years ago by snover

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.

comment:4 Changed 9 years ago by abraham@…

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 :-)

comment:5 Changed 8 years ago by dmethvin

Milestone: 1.next1.7
Owner: set to dmethvin
Status: openassigned

comment:6 in reply to:  5 Changed 8 years ago by abraham@…

Replying to dmethvin: yes ... could you please implement the suggested fix in the official release ?

comment:7 Changed 8 years ago by whale

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 ?

comment:8 Changed 8 years ago by glenn@…

I need this too ! 1.7 ?

comment:9 Changed 8 years ago by dmethvin

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?

comment:10 Changed 8 years ago by abraham@…

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.

comment:11 Changed 8 years ago by dmethvin

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.

comment:12 Changed 8 years ago by abraham@…

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 :-)

comment:13 Changed 8 years ago by Aaron Spaulding

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.

comment:14 Changed 8 years ago by dmethvin

Milestone: 1.71.8

Moving to 1.8 for a comprehensive solution.

comment:15 Changed 8 years ago by dmethvin

Owner: dmethvin deleted
Status: assignedopen

comment:16 Changed 8 years ago by mikesherov

Resolution: duplicate
Status: openclosed

comment:17 Changed 8 years ago by mikesherov

Duplicate of #7986.

comment:18 Changed 8 years ago by dmethvin

Milestone: 1.8

comment:19 Changed 7 years ago by odegroot

Fixed in 1.7.2, along with #7986.

Note: See TracTickets for help on using tickets.