D
David Mark
That way absolutely-positioned children of BODY stay inside body. I do
this a lot.
Why? To avoid the bizarre "edge cases" (pun intended) involving the
HTML element?
And that's why it's weird. You have a 10px margin around body.
#adiv's containing block is HTML.
BODY is not (or shouldn't be) a majical element.
Weird is a good description for the behavior of the various browsers
with regard to absolutely positioned elements without positioned
parents. Your strategy of positioning the body seems like a good way
to avoid some of the quirks.
My Definition:
offsetParent - a containing block that is offset by margin or left/top
values.
I assume that is your abridged definition.
Anne van kesteren started this 2 years ago:
Editor's Draft 9 December 2007
"1. If any of the following holds true return null and stop this
algorithm:
* A is the root element.
* A is the HTML body element.
* The computed value of the position property for element A is
fixed.
2...
3. Return the nearest ancestor element of A for which at least one of
the following is true and stop this algorithm if such an ancestor is
found:
* The computed value of the position property is not static.
* It is the HTML body element.
* The computed value of the position property of A is static and
the ancestor is one of the following HTML elements: td, th, or table.
"
http://dev.w3.org/cvsweb/csswg/cssom-view/Overview.html?rev=1.2#offse...
I would hope that this spec be forgotten a new one started.
Yes, I glanced at it recently and it seems out-of-touch with reality.
The spec is self contradictory, and thus impossible to implement
correctly.
Always a bad thing for a technical specification.
What is A's offsetParent?
if A is BODY then
offsetParent is null
As such, A can then have neither offsetTop, nor offsetLeft. BODY can
have margin, top, left, border, and position.
All of these things move the BODY element.
For some reason, containing block doesn't come up in the document at
all. Nor does "initial containing block".
The spec is inaccurate to the point of being almost completely
fictitious. The damage of having such a spec is considerably large.
I agree. Hopefully it will not become the basis for a standard.
The damage can be seen in Opera, Mozilla, and Safari. These browsers
have seemed to have attempted to implement the (impossible) spec. None
of them get it right, of course. It's impossible.
Now I know who caused this mess. Thanks Anne!
This is a simple test that barely scratches the surfacehttp://dhtmlkitchen..com/ape/test/tests/dom/inline-offsetTop.html
getBoxObjectFor is for XUL
Ah, there is only XUL. I wonder why it works so well for (X)HTML
documents? Perhaps it is just a lucky coincidence. I can't remember
where I got the idea to use it, but it seemed like a sound idea at the
time.
When checking drop target coords, with scrolling or moving dropTargets
(while dragging), coord checks must be done continually, while
Drop targets inside of scrolling containers that can be scrolled
during the drag operation I can see. But moving drop targets? Other
than a video game of some sort, the application for that eludes me.
dragging.
There might be a better strategy for checking coords.
Certainly. For the scrolling example, the dragged element could share
the same positioned parent as the drop targets, which could be
positioned absolutely. Then the overlap logic would only need to use
computed styles.
Besides, I've got load-time constant for determining certain things
about the document, those things could easily be different in the
framed document. It is an edge case that is not worth testing. It
Yes, if a document that triggers standards-based layout contains an
IFrame that triggers quirks mode, things could get very ugly. This is
something I need to document.
might be worth testing to throw an error if el.ownerDocument != doc;
Then the user knows because it fails right away.
Why just use ownerDocument?
Because it can't be assumed to be there. The fallback branch isn't
too involved.
I didn't consider that. I reading some old thread where it says that
IE5.0 doesn't support |in|, so my library will break there. I use |in|
That's the biggest reason I don't use it in low-level code like this.
a lot. It's really the only way to tell if an object has a property.
See the three methods recently discussed in the thread about Peter's
feature testing article.
var IS_BACK_COMPAT = document.compatMode === "BackCompat" ||
documentElement && documentElement.clientWidth === 0);
It's a stronger inference than compatMode (value or absence) alone.
Not perfect, but better.
I don't think that will work. For instance, I know the
documentElement in IE5 has a non-zero scrollHeight/Width. I tried
everything to come up with a proper feature test for this. I finally
came up with a partial solution that uses a multiple object inference
only until the page has been scrolled (then it knows for sure which to
use.) In my entire library, this is the only quirk that I couldn't
find a pure feature test for.
Does getComputedStyle provides more accurate results?
Well, they are apples and oranges, but other than left/top and height/
width for statically positioned elements, I have found no problems
with getComputedStyle in Opera.
Opera has some css rounding issues anyway IIRC.
I haven't run into those in Opera.
getting styles is painful topic worthy of a new group. I can't even
get currentStyle.clip in IE. I found only clipTop/Left, et c.
Interesting. IE's implementation of clip is completely bizarre. I
couldn't include a two line function that "unclips" an element in my
core build as it required conditional compilation. For this reason,
it is offered only as an add-on, which is only required for certain
animation effects.
I was probably confused with setting fontWeight or zIndex.
style.fontWeight = 101 => Error
style.zIndex = 1.2 => Error? I can't remember. IE is less forgiving.
That looks like a sure error to me.
There are issues with browsers rounding pixel values:http://groups.google.com/group/comp...p://ejohn.org/blog/sub-pixel-problems-in-css/
Thanks. I'll skip that one.
Try using a torture case and you'll see more errors.
My test page layout is fairly torturous I think, but within reasonable
limits.
Here's a really weird one. I have a "grow" effect that can optionally
size the font of the element. Using my em-based layout (which was my
first stab at aligning to a baseline grid), I found that setting
inline font sizes to their cascaded or computed values would make the
fonts change in size (which makes no sense to me) and this only
happened at certain text size settings (e.g. larger, smaller,
smallest, but not medium.) However, if I set the inline font size
style to what I know is the cascaded value before I run the animation,
then all is well (the fonts have already jumped in size.) That is the
one strange workaround I had to implement in all of the animation
tests. I still don't understand what the deal was with that (and
don't really care.) I suspect my CSS is just too convoluted, but the
baseline grid does work well in all of the browsers I have tested.
I used fontSize = "777px";
with 1.18em on two nested elements.
It's a real torture test. Amazinly, MOzilla got it. webkit's 2px off.
What Webkit browser do you test with? Windows Safari Beta? That
browser still has some serious issues. I wonder if they will ever
finish it. Despite it being a Beta, I duly added some quirk detection
logic in a few places to make the unit tests behave (more as an
exercise in feature testing than anything else.) I still have an
issue when I replace a static (and streaming) Flash movie with one
created on page load (to prevent the "click to activate" problem) and
Safari's status bar indicates that it is still loading the replaced
object element. I've seen it crash when interacting with Apple's own
Quicktime plug-in as well. Whatever.
I don't like seeing failing tests, but I'm leaving it in. It's a way
to say:
"if you try to get an exact calcuation off EM units, it might be off a
few px in some edge cases on some browsers."
Makes sense.
testGetOffsetLeftFloatingPointEM : function() {
var fontSize = "10px";
var target = document.getElementById("target");
var container = document.getElementById("container");
var c1 = document.getElementById("c1");
document.documentElement.style.fontSize =
document.body.style.fontSize =
c1.style.fontSize =
container.style.fontSize =
target.style.fontSize = "777px";
container.style.borderLeft =
c1.style.borderLeft = "1.18em solid red";
target.style.marginLeft = "1.18em";
target.style.left = 0;
var expected = Math.round(777 * 1.18 * 3);
var actual = dom.getOffsetCoords(target);
Assert.areEqual(expected, actual.x, "getting computed coords from
EM values failed.");
Interesting.
I'm not testing in older browsers. I am going to try to get it going
in IE6, Safari 2, FF 2, Opera 9.
I am going to exit the function if neither getCOmputedStyle nor
getBoundingRect are supported.
To be future-proof, you need getComputedStyle or
(getBoundingClientRect AND clientLeft/Top.)
I hope you're not talking about the Dean Edwards hack that's used in
jQuery's css(). I've tested it thoroughly. The rounding errors are as
bad as Opera (or worse).
In the case of IE computing the pixel-based value, I am talking of a
modified version of that hack. It has worked thus far for me. The
unmodified original was clearly no good.
Using that hack, it's possible to have close results.
style.fontSize = "10px";
style.height= "2em";
You can get an acceptible result.
When I started using bigger numbers, I got rounding errors.
I probably will too. The lesson is that nothing is going to be 100%
perfect for all cases in all browsers. I figure that the best I can
shoot for is 99%. It seems to me that the currently popular libraries
take a stance like "three out of four ain't bad."
Webkit returns 'auto' when margin: auto and left is undeclared.http://www.dhtmlkitchen.com/test/bug/getComputedStyle.html
My gCS wrapper will never return "auto", but instead returns null.
IRC, IE's currentStyle property (which is cascaded
Hmm.
There's also style.pixelTop and curentStyle.pixelTop (Opera).
I don't use those, except in the aforementioned hack to convert
cascaded styles to pixel units in an IE-only branch (Opera always uses
getComputedStyle.)
Yes, but often much faster when you don't. I think that most
applications will not need to worry about element scroll offsets.
I need to get that profiler going.
Yes, but I think the extra effort is worth it. These sorts of
functions are always going to be a bottleneck, so I endeavor to design
systems that call them as infrequently as possible (if at all.)
var TABLE = /[A-Z]/.test(documentElement.tagName) ? "TABLE" : "table";
Now I can use it as a constant:
(parent.tagName === TABLE
Interesting solution.
Only 0 would make sense to me.
Or null I would think. Regardless, Opera, FF and others go ahead and
return what they think is the offset position in pixels (as mentioned,
Opera gets them wrong when borders are involved.)
When an element has position: static, top and left values do not
apply.
Exactly, so I consider the above-mentioned behavior a non-standard
bonus feature. Needless to say, I do not rely on its presence.
I've got Opera 9.25 and it doesn't do that.
That means they fixed it and my code will skip the workaround in that
and subsequent versions. Isn't feature testing wonderful?
It seemed simple enough. I guess it's making the code messy the way I
have it?
It is definitely confusing to see a timeout in there.
Sure, why not?
I don't know. It is the last thing I am worried about at the moment.
I figure when I get to the unit test for the style switcher, I will
create some more distinct (and perhaps more appealing) alternate
styles.
I've gone and set the height to "0" (string).
Good.
I want to see the twitch you mentioned. I generally dislike making
changes without a proven reason.
Think about it. If the statically positioned element added at the
bottom has a height, then the page will grow longer. Removing it will
restore the previous height. Watch the scrollbar closely during the
load and you will see it jump briefly to reflect the change.
That's why I need a demo.
Only browsers that do not support getBoundingClientRect get there.
I see.
I don't doubt that it is and will continue to be a source of pain for
a lot of people, including members of the Webkit team.
I bet they struggled - and will continue to struggle - with Anne van
Kesteren's "unofficial" spec.
I imagine so.
I wonder how many man hours (or months) have been put into
compensating for this careless mistake?
I know I spent at least a few days tearing my hair out over the
various "edge cases" (pun intended.)
I'm going to have a look at getElementPosition().
Have fun.
[snip]