Bug Tracker

Modify

Ticket #5520 (closed bug: duplicate)

Opened 4 years ago

Last modified 9 months ago

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:
Blocking: Blocked by:

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

box_model_test6.html Download (2.1 KB) - added by whale 4 years ago.
illustration of the offset bug occurring under IE8 box-sizing: border-box model

Change History

Changed 4 years ago by whale

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

comment:1 Changed 4 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 3 years ago by snover (previous) (diff)

comment:2 Changed 3 years ago by dmethvin

  • Component changed from unfiled to dimensions

comment:3 Changed 3 years ago by snover

  • Priority changed from major to low
  • Status changed from new to open
  • Version changed from 1.3.2 to 1.4.4
  • Milestone changed from 1.4 to 1.4.5

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

comment:4 Changed 3 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 follow-up: ↓ 6 Changed 23 months ago by dmethvin

  • Owner set to dmethvin
  • Status changed from open to assigned
  • Milestone changed from 1.next to 1.7

comment:6 in reply to: ↑ 5 Changed 22 months ago by abraham@…

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

comment:7 Changed 22 months 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 21 months ago by glenn@…

I need this too ! 1.7 ?

comment:9 Changed 20 months 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 20 months 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 20 months 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 20 months 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 20 months ago by AaronAsAChimp

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 20 months ago by dmethvin

  • Milestone changed from 1.7 to 1.8

Moving to 1.8 for a comprehensive solution.

comment:15 Changed 19 months ago by dmethvin

  • Owner dmethvin deleted
  • Status changed from assigned to open

comment:16 Changed 17 months ago by mikesherov

  • Status changed from open to closed
  • Resolution set to duplicate

comment:17 Changed 17 months ago by mikesherov

Duplicate of #7986.

comment:18 Changed 16 months ago by dmethvin

  • Milestone 1.8 deleted

comment:19 Changed 9 months ago by odegroot

Fixed in 1.7.2, along with #7986.

Please follow the  bug reporting guidlines and use  jsFiddle when providing test cases and demonstrations instead of pasting the code in the ticket.

View

Add a comment

Modify Ticket

Action
as closed
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.