Opened 10 years ago

Closed 10 years ago

#9404 closed defect (invalid)

dojo.marginBox() returns wrong left and top values for crazy layouts in IE

Reported by: cb1kenobi Owned by: Douglas Hays
Priority: high Milestone: 1.4
Component: HTML Version: 1.3.0
Keywords: Cc: nicola.rizzo@…, alex
Blocked By: Blocking:

Description

Stumbled across a scenario where IE7 returns the incorrect node.offsetLeft and thus causing dojo.marginBox() to return the wrong value.

<body>
	<div style="background-color:#f00;position:absolute;left:100px;top:110px;">
	  	<div style="background-color:#ff0;">
			<div style="background-color:#0f0;margin:5px;padding:20px;position:relative;left:0;top:0px;">
				<div id="box" style="background-color:#ccc;width:100px;height:50px;">box</div>
			</div>
		</div>
	</div>
</body>

IE7 appear to be adding the parent's margin when it shouldn't be.

A solution is to hack a scenario for IE7 to subtract the parent node's offsetLeft.

I attached a test case and a patch.

I should note that IE6 has the same problem, but is slightly worse than IE7, in which case IE6 would require it's own hack. Opera 8.5 has problems with the left value, but also has problems with the top value too.

Attachments (5)

dojo.marginBox.patch (448 bytes) - added by cb1kenobi 10 years ago.
test_getMarginBox_bug.html (1.1 KB) - added by cb1kenobi 10 years ago.
test_getMarginBox_bug.2.html (2.6 KB) - added by cb1kenobi 10 years ago.
test_getMarginBox_bug.3.html (2.8 KB) - added by cb1kenobi 10 years ago.
IE position errors.gif (128.3 KB) - added by cb1kenobi 10 years ago.

Download all attachments as: .zip

Change History (14)

Changed 10 years ago by cb1kenobi

Attachment: dojo.marginBox.patch added

Changed 10 years ago by cb1kenobi

Attachment: test_getMarginBox_bug.html added

comment:1 Changed 10 years ago by cb1kenobi

Summary: [patch] [cla] dojo.marginBox() returns wrong left value for crazy layouts in IE7dojo.marginBox() returns wrong left value for crazy layouts in IE7

OK, that patch will not work. I updated my test with another scenario where it doesn't work.

Changed 10 years ago by cb1kenobi

comment:2 Changed 10 years ago by cb1kenobi

I started trying to fix this. From what I read, node.offsetLeft is the number of pixels from the node's left edge to the left edge of the node.offsetParent. In IE7, it's like it's calculating the distance from the left edge to whichever parent node that has an explicit position.

Something that might work would be to loop through parentNodes until you hit the node.offsetParent and sum up the left padding, left border width, and left margins. Most likely the node.offsetParent == node.parentNode, so it's a single loop.

comment:3 Changed 10 years ago by alex

I'm worried about this patch since I'm suspicious that just testing for IE 7 is sufficient to diagnose the problems. Does the node have layout? And what about IE 8 in IE 7 mode? Inquiring minds want to know!

comment:4 Changed 10 years ago by alex

Cc: alex added

comment:5 Changed 10 years ago by cb1kenobi

Summary: dojo.marginBox() returns wrong left value for crazy layouts in IE7dojo.marginBox() returns wrong left and top values for crazy layouts in IE

Yeah, the above patch is bad. I've attached my latest test cases (v3). I also attached an image with screenshots of IE6, IE7, IE8 in various modes, and FF3 for reference.

The test case has 2 squares. The first is a floated left div. The second is a position absolute div.

IE8 was working until I added yet again another nested div, then it got confused. So, now all versions of IE have issues.

And it appears this is no longer exclusive to the left value, but also the top value.

For the curious, I discovered this bug while trying to use dojox.fx.split on a div that was nested in a div that was positioned absolute. The ticket for that is #9394. After fixing that issue did I discover this issue.

I tried messing around with manually computing the correct offsetLeft value, but given the short amount of time, I haven't found a solution. I'm still investigating the possibility of manually computing the correct offsetLeft and offsetTop based on analyzing margins, borders, and padding of the node and it's parent nodes.

Changed 10 years ago by cb1kenobi

Changed 10 years ago by cb1kenobi

Attachment: IE position errors.gif added

comment:6 Changed 10 years ago by Adam Peller

Owner: changed from anonymous to sjmiles

comment:7 Changed 10 years ago by bill

Component: CoreHTML

comment:8 Changed 10 years ago by bill

Owner: changed from sjmiles to Douglas Hays
Priority: highestnormal

Doug, is this working correctly in dojo.position()? If so I think we can close this as wontfix.

comment:9 Changed 10 years ago by Douglas Hays

Resolution: invalid
Status: newclosed

The problem is that on IE, the offsetParent for the position:absolute div is not the same as the offsetParent for the "hello" div, and thus marginBox left and top for 1 makes no sense in context of the other. You can make this work by using the new dojo.position() method. Here's the modified user code that correctly positions the black square on all browsers:

var box1pos = dojo.position(dojo.byId("box1_1"));
// either set left and top to 0, or call getComputedStyle to add on existing values
dojo.style("box1_2", { left: "0px", top: "0px" });
var box2pos = dojo.position(dojo.byId("box1_2"));
dojo.style("box1_2", {
        left: (box1pos.x-box2pos.x) + "px",
        top: (box1pos.y-box2pos.y) + "px"
});
var box1pos = dojo.position(dojo.byId("box2_1"));
// either set left and top to 0, or call getComputedStyle to add on existing values
dojo.style("box2_2", { left: "0px", top: "0px" });
var box2pos = dojo.position(dojo.byId("box2_2"));
dojo.style("box2_2", {
        left: (box1pos.x-box2pos.x) + "px",
        top: (box1pos.y-box2pos.y) + "px"
});
Note: See TracTickets for help on using tickets.