getComputedStyle() returns an empty style declaration for detached elements. Firefox returns a full style declaration including inherited properties (starting from the root of the detached element's tree).
I'm also running into this bug. It affects Windows Safari, both on the latest Safari release and the WebKit nightly.
I have a 20-line HTML file that exercises the bug if you'd like me to send you it.
Jon, please attach your test case reduction. Thanks!
Created attachment 22698 [details]
Example of the getComputedStyle bug
The attached HTML file exercises the bug. In Firefox, you correctly get an alert of '10px'. In Safari, you get ''. You can uncomment the appendChild call to see that getComputedStyle acts as intended in both Firefox and Safari if the element is appended to the document body.
Isn't this "expected" based on our implementation? We use the resolved style for computing this. So we'd have to do a manual style-resolve in this case, since a detached element is going to have no renderer.
SVG had to do some manual style resolution. I guess for a detached element it's relatively easy, since you're resolving w/o a parent, so only #id selectors and * selectors apply.
We could fix this I suppose, but it's kind of odd that someone is depending on this. It's not like any style changes you make will have any meaningful effect while detached, so what are you checking for anyway? :)
I don't have the original code any more, but if I remember correctly, this was my use case :
I was creating a bunch of elements dynamically, throughout the lifetime of the page (as opposed to once on page load). Whenever I inserted them, I needed to find their dimensions (using getComputedStyle) in order to position them correctly.
Which would be fine, except it turns out that getComputedStyle is pretty slow. So I created some prototype elements on startup that I could run getComputedStyle on, cached the results, and used the precalculated values every time after that. Which was fine in Firefox, but obviously broken in Safari given the prototype elements were never inserted into the page.
I guess I ended up inserting them into a hidden div to get the style, then deleting them again.
I'm sure there was some reason why I couldn't just do it on the first time I added an element, but nothing's coming to mind...
Per spec, getComputedStyle() returns the computed style, and a node that isn't a document by definition doesn't have a computed style. Whether that's desireable or not is another story; maybe we should redefine getComputedStyle()... that's Anne's spec, I believe.
In our application, we render our pages off-screen before attaching them to the document because in a couple popular browsers the performance of off-screen (detached) DOM creation is an order of magnitude greater than on-screen (attached) DOM creation. Part of our rendering involves manually setting the width and heights on certain elements to fill the screen. (We do this manually for cross-browser compatibility.) If we can't know the margins of elements, then we can't size other elements appropriately.
Please fix this bug! Thanks.
The spec has changed to expect the Firefox behavior: http://dev.w3.org/csswg/cssom/#extensions-to-the-window-interface
*** Bug 39250 has been marked as a duplicate of this bug. ***
The spec has indeed changed:
This shows that disconnected nodes should still resolve to computed values for disconnected nodes, with the computed value defined as: "the result of resolving the specified value insofar as possible without formatting the document, as defined in the "Computed value" line of the property definition tables."
Indeed, Firefox resolves this correctly now, but alas IE9 and Opera do this incorrectly according to the spec.
FWIW, It's also reared its head as a bug reported in jQuery: http://bugs.jquery.com/ticket/9338
*** Bug 83867 has been marked as a duplicate of this bug. ***
Related CSSWG discussion http://lists.w3.org/Archives/Public/www-style/2012Oct/0362.html.
Just faced this issue today as I wanted to know the default style applied to a certain kind of element (tagName). For info, my webkit fix is to insert the element into the HEAD hoping it doesn't trigger any relayout nor too many observable effects.