Working on a cross browser code the other day, I stumbled upon yet another difference in browsers behaviour and dom+javascript implementation. (first published 26OCT09) The difference is in handling CSS properties on the “newborn” elements, while they are still detached from the document.
1 2 3 4 5 6 7 8 9 10 |
// var btn = document.createElement("button"); btn.style.color = "red"; var clr = window.getComputedStyle(btn, null) .getPropertyValue("color") ; // In CHROME 4.x clr is empty string here // Also re-checked in Chrome Version 22.0.1229.94 // // Update 27OCT12: in IE9 clr is "rgb(255, 0, 0)" // |
Above code works in IE & FF, but not in CHROME (see the re-check update bellow). This is because CHROME implementation does not allow setting/getting style properties on the newly made and detached DOM elements. So if one uses (for example) getComputedStyle()
,on this kind of elements, the one will receive nothing, aka empty string. While in FF1 , the one will be able to do CSS related operations on newly made detached elements. This is also true when using jQuery. The following code will not work in CHROME, because of the same reason:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// // jQuery 1.7.2 // make DOM node, but keep it detached // specifically set color to be red and important // $div = $("<div style='color:red!important' ><div>" + "<div><a href='about:blank'>ABC</a></div>" + "</div></div>") ; // // now get to link node ("A") // inside the little div made above // $div.find("A").css("color"); /* above call returns : "red" in IE < 9 , "rgb(0, 0, 128(" in IE > 8 rgb(0,0,128) in FF and an emptry string in CHROME 22.0 */ |
This has to be “taken care of”. Libraries like jQuery (and my own “DBJ”) should “know” there is this issue in existence. So that code , like the one above works. To solve his issue, in the context of my library I have added this feature check also. I am calling it css_on_newborns
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// // browser support checks , specific for DBJ library // (function( dbj ) { dbj.browser = { support: { // // CSS properties on new elements still // not attached to the document // Let's assume this works. As it does in IE. // css_on_newborns: true } }; // // check if CSS properties get/set is supported on // newly created but still detached elements // check W3C compliant browsers // if (window.getComputedStyle !== undefined) { var btn = document.createElement("button"); btn.style.color = "red"; dbj.browser.support.css_on_newborns = ( "" !== window.getComputedStyle(btn, null) .getPropertyValue("color")); delete btn; } })( dbj || (dbj = {})); |
(Slightly) moot point is , if the document.createElement()
, above will work before the dom is “ready” to be used , and after a page load? As every other library author (for example the author of Sizzle) I am pretty sure this will work, any time browser is ready for the javascript to be parsed and executed. Hence, the code does it “there and then” and leaves the result in a property. One could imagine a function which will do this check only once and return the result on each consecutive call, but in this case that would be an overkill.
Update 27OCT12
Just checked my Chrome (Version 22.0.1229.94). And … yes, this is still the case in Chrome. If You create DOM element in code, change it’s style in code and then read the values You just have changed, the style object properties will read as empty strings. Just like the source on the top of the post shows.
1: I should mention here that this does not apply to IE since ie has no getComputedStyle()
method available.Update: IE9 and better has this method avaliable. And yes it natively supports css on newborns.
2 thoughts on “Does your browser support CSS on newborns ?”
Sir, you’ve just made my day!
When playing with GWT this code worked perferctly in FF but not in WebKit/Chrome/Chromium:
Temporary fix is to change page initialization order.
Just ensure that element (Panel) is added to parent (RootPanel in my case).
This is what makes Element attached in GWT.
This works:
@Jan Well Sir, what can I say but to thank You …