Side navigation
#8362 closed bug (patchwelcome)
Opened February 23, 2011 02:16PM UTC
Closed April 18, 2012 12:20PM UTC
Last modified December 19, 2013 05:22AM UTC
postion and offset differing in browers when CSS transforms in use
Reported by: | moronicbajebus | Owned by: | moronicbajebus |
---|---|---|---|
Priority: | low | Milestone: | 1.next |
Component: | dimensions | Version: | 1.5 |
Keywords: | standards | Cc: | |
Blocked by: | Blocking: |
Description
Example: http://jsfiddle.net/8j6AF/1/
When CSS transforms are used with scaling, Gecko and Webkit report differ values for offset and position. They report the same value for the CSS value for left and top.
Firefox appears to report the position ''before'' it is transformed.
Webkit appears to report the position ''after'' it is transformed.
Attachments (0)
Change History (25)
Changed February 23, 2011 10:46PM UTC by comment:1
component: | unfiled → dimensions |
---|---|
keywords: | → browserbug browser-firefox |
owner: | → moronicbajebus |
priority: | undecided → low |
status: | new → pending |
Changed March 09, 2011 11:17PM UTC by comment:2
FYI: I think it's actually a bug in everything else. I'm pretty sure that element.getBoundingClientRect() (which is the basis for jQuery's offset() function) is supposed to return coordinates ''before'' the transform is applied. In other words, you're supposed to be able to continue manipulating objects as though no transform has been applied.
The following offset function does return the right (ie "pre-transform" coordinates):
function getOffset( el ) {
var _x = 0;
var _y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
_x += el.offsetLeft;
_y += el.offsetTop;
el = el.offsetParent;
}
return { top: _y, left: _x };
}
Changed March 10, 2011 01:08PM UTC by comment:3
Not so sure if this is a firefox bug. At least. trident & presto layout engines seems to work the same way as mozilla, so it is only webkit that does this different.
Changed March 14, 2011 06:31PM UTC by comment:4
status: | pending → open |
---|
We've discussed this and we think it would be of benefit to first petition vendors to try getting these changes brought into place on their end. We can then standardize as needed.
Changed March 15, 2011 01:06PM UTC by comment:5
This affects the jQuery UI Draggable plugin as well. When an element is rotated and is draggable, the element gets displaced a few pixels before the startDrag event is triggered. Debugging, I found out that this is caused by the top and left position returned by webkit (which returns the upper left corner's position of the element whereas Gecko returns the upper left position of the bounding rect box).
A quick test case can be set up by just creating a draggable element and then applying a rotation of 45deg to it. Then you only need to drag the element and you would see that the element moves up a few pixels on the first 'mousemove' event, then the dragging works well.
This guy also realized of this and, if you check the final example, you would see how the images have a little awkward movement when you start to drag them: http://www.elated.com/articles/smooth-rotatable-images-css3-jquery/ (check 'step 10' and the final example)
Changed March 15, 2011 01:17PM UTC by comment:6
Here's a quick test case:
http://jsfiddle.net/qnxGE/2/ (use webkit)
Check how the helper is rendered with an incorrect initial position.
PLEASE NOTE, that although I'm using jQuery UI in the example this is not a bug in jQuery UI itself as it relies on the information the method offset() returns, I'm only using it because is more easy to provide an example.
Changed August 10, 2011 09:48PM UTC by comment:9
To rectify the problem in draggable use dhilowitz's code to calculate the top and left before transformation:
function get_unrotated_left_top(el) {
var _x = 0; var _y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
_x += el.offsetLeft; _y += el.offsetTop; el = el.offsetParent;
}
return { top: _y, left: _x };
}
Then in _mouseStart: function(event) { see my changes here:
The element's absolute position on the page minus margins
AD custom changes start - stop draggable jumping after transformed
var pos = get_unrotated_left_top(this.element.get(0));
this.offset = pos;
/* orig - start
this.offset = this.positionAbs = this.element.offset();
orig - end */
// AD custom changes end - stop draggable jumping after transformed
this.offset = {
top: this.offset.top - this.margins.top,
left: this.offset.left - this.margins.left
};
Changed January 04, 2012 05:11PM UTC by comment:10
http://jsfiddle.net/z3asJ/ is a fork of the original jsfiddle, where I added an evolved version of Firebug's getViewOffset
function (1.0.5, IIRC - MIT licensed, used in its node highlighting code), which I have adapted for monkeypatching jQuery UI Draggable 1.8.16 to work right (for details, see http://stackoverflow.com/questions/3523747/webkit-and-jquery-draggable-jumping/8730874#8730874), instead of relying on the not-quite-working offset()
.
I'd be happy if jQuery adopted this, and even happier if browsers exposed these calculations natively in the DOM, so we don't have to.
Changed April 17, 2012 09:53PM UTC by comment:11
Just want to add my voice to those noting this isn't a Firefox bug. Maybe tags should be updated? This is a pretty big deal imho
Changed April 18, 2012 12:12PM UTC by comment:12
#11114 is a duplicate of this ticket.
Changed April 18, 2012 12:20PM UTC by comment:13
keywords: | browserbug browser-firefox → standards |
---|---|
resolution: | → patchwelcome |
status: | open → closed |
Per #11114, affects width and height as well. See ecmanaut's comment 10 above for a workaround. There is no way we'd land that much code for a case like this; take that code and turn it into a plugin. In the meantime we'll lobby for the browsers to expose this information rather than us (or you) having to recalculate something they already know.
Changed August 14, 2012 11:31PM UTC by comment:14
I thought jQuery's value proposition was cross-browser compatibility? I'm surprised the official word seems to be to petition vendors to clean up their act. I though this was jQuery's claim to fame, it wrapped the vendor's inconsistencies for us.
Changed August 20, 2012 06:00PM UTC by comment:15
#12352 is a duplicate of this ticket.
Changed November 14, 2012 03:06PM UTC by comment:16
#12887 is a duplicate of this ticket.
Changed June 23, 2013 04:51PM UTC by comment:17
#14056 is a duplicate of this ticket.
Changed July 09, 2013 03:06AM UTC by comment:18
I agree. I thought that the idea of jQuery is to provide an interface which works cross-platform. Not that we have to manually discover that things don't work in some browsers.
I suggest that jQuery provides both functions to get position and size of elements before and after CSS transformations. With all CSS transformations getting more and more popular, jQuery API should be extended to support that as well.
Changed July 09, 2013 04:51AM UTC by comment:19
OK, it seems the issue is that width and height do not return width and height after rotation. Position is OK.
Changed October 13, 2013 12:23PM UTC by comment:20
#14440 is a duplicate of this ticket.
Changed December 09, 2013 09:37AM UTC by comment:21
Here is a fix of this bug that works.
Changed December 09, 2013 10:33AM UTC by comment:22
Replying to [comment:21 jimmitjoo@…]:
Here is a fix of this bug that works. http://jsbin.com/ojoyuc/4
yes, its working, but when/if the drag-able element is scaled or rotate, but not when parent element is scaled or rotate.
Changed December 17, 2013 11:06PM UTC by comment:23
#14640 is a duplicate of this ticket.
Changed December 18, 2013 10:52AM UTC by comment:24
Why is this ticket closed while this is obviously still a issue?
Not that it would be performant at all, but how about cloning the element, removing the translation and then checking the offset/position?
Changed December 19, 2013 05:22AM UTC by comment:25
Replying to [comment:24 leongersen@…]:
Why is this ticket closed while this is obviously still a issue? Not that it would be performant at all, but how about cloning the element, removing the translation and then checking the offset/position?
If you test the original test <http://jsfiddle.net/8j6AF/1/>, you'll see that the same thing is reported by all browsers instead of getting different values.
Thanks for taking the time to contribute to the jQuery project by writing a bug report and providing a test case!
After checking your report and test case I fail to see how this is a jQuery issue. To me this looks like a bug in Firefox and thus should be report to them.
Please report back if you can provide information on how this is bug in jQuery or if you know of a way to workaround this. If you happen to file this a bug on the Firefox bug tracker please add the link here too.