IE won't allow document.createElement('style')

If you try to add style declarations in the head of a document, IE borks at the name 'style' - "unexpected call to method or property access".

I guess its getting confused between the head element <style> and the object property .style?

Test page Workaround is not included
Reported by: Ross Howard.

Explorer 5-6 Windows, Explorer 7, Explorer Mac | Reported on 18 January 2006.

This site is no longer maintained. I’m sorry, but it’s just too much work for too little return. You can continue to browse old bug reports, though.




Search reports by browser:

Atom RSS

Comments

(Add your own)

1 Posted by Milo van der Leij on 18 January 2006 | Permalink

Actually, the error "Unexpected call to method or property access" seems to come from the line "styles.appendChild(newStyle)".

Trying to use innerHTML or innerText instead of appendChild causes an "Unknown runtime error."

2 Posted by Krijn Hoetmer on 19 January 2006 | Permalink

Off topic:

"I guess its getting confused between the head element <style> and the object property .style?"

<style> isn't escaped, which stops the page from rendering in Opera (and IE)..

3 Posted by Ross Howard on 20 January 2006 | Permalink

I'm not sure what you mean. isn't escaped?

It renders fine in opera for me...

4 Posted by Krijn Hoetmer on 20 January 2006 | Permalink

http://validator.w3.org/check?uri=http://www.quirksmode.org/bugreports/archives/2006/01/IE_wont_allow_documentcreateElementstyle.html

5 Posted by Nick Fitzsimons on 24 January 2006 | Permalink

I would argue that your code is not manipulating the DOM correctly: you should be using createComment, rather than putting the comment syntax inline in your createTextNode call; then add the textNode containing the CSS to the comment. See http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-core.html#ID-1334481328

6 Posted by Tino Zijdel on 24 January 2006 | Permalink

Nick: I'd say the comment-tags are completely unnecessary. In an XHTML-environment you certainly don't want to put HTML-comments around styles or scripts. It's an old-school habbit that ought to be forgotten.

7 Posted by Nick Fitzsimons on 24 January 2006 | Permalink

Tino: I'd tend to agree with you. In addition, when the text node is created the browser is potentially going to be forced to convert it into a comment node when it's appended to the DOM tree. A quick look with Firefox's DOM Inspector and MS's Script Editor debugger suggests that's not what's actually happening, but the Script debugger shows that the error is with the line

styles.appendChild(newStyle);

and not with creating the "style" element.

Trying to create a "script" element and appending a text node (free of comment markup) to it causes the same error. Creating a "title" element and appending a textNode works, but gives a "Type mismatch" when appending it to the head.

I think this one could do with deeper exploration... it's something horrible to do with COM, I think.

8 Posted by David Chan on 1 February 2006 | Permalink

I got your example to work in IE6 by changing your createTextNode line to:

var newStyle = document.createTextNode('body { background-color: yellow; }');

9 Posted by David Chan on 1 February 2006 | Permalink

Nevermind. I had something wrong with my test setup. Disregard the last post.

10 Posted by Alex on 7 February 2006 | Permalink

The given script works absolutely fine for me on IE6SP2.

WRT to comments etc. for inserting style, I prefer to use the built in methods for adding style rules... they work fine in this example, which is designed to add css rules supplied in a div- this allows for adding CSS imformation from within the tag- e.g. if working from inside a PHP script where the head is inaccessible:


<div id=cssinfo>
body{background-color:#00f !important;}
a:hover{text-deocation:none;}
a{color:red;}
<div>
<script type="text/javascript">
rawsheet = document.getElementById("cssinfo");
newcss = document.createElement("style");
newcss.type="text/css";
newcss.media="all";
document.getElementsByTagName("head")[0].appendChild(newcss);
cssrules = rawsheet.innerHTML.split("}");
newcss = document.styleSheets[0];
if(newcss.rules) { //IE
for(i=cssrules.length-2;i>=0;i--) {
newrule = cssrules[i].split("{");
newcss.addRule(newrule[0],newrule[1])
}
}
else if(newcss.cssRules) { //Firefox etc
for(i=cssrules.length-1;i>=0;i--) {
if (!/\s$/.test(cssrules[i])) newcss.insertRule(cssrules[i]+"}",0);
}
}
rawsheet.parentNode.removeChild(rawsheet);
</script>


If you feel real generous, test it in your browser!

11 Posted by Fredrik Johansson on 1 March 2006 | Permalink

This works for me, doesnt it work for you?

var cssStr = "div {color:blue;}";
var style = doc.createElement("style");
style.setAttribute("type", "text/css");
if(style.styleSheet){// IE
style.styleSheet.cssText = cssStr;
} else {// w3c
var cssText = doc.createTextNode(cssStr);
style.appendChild(cssText);
}

Regards
Fredrik Johansson

12 Posted by Jerome Devost on 23 March 2006 | Permalink

You get the same error if you want to add text to a 'script' node. Use this instead (in IE):
var oScript = document.createElement('script');
oScript.text = sScriptCode.

13 Posted by didkobravo on 7 August 2007 | Permalink

IE ain't complaining when its createStyleSheet method is used instead of document.createElement('style')

http://msdn2.microsoft.com/en-us/library/ms531194.aspx

here's the example i've been messing around with.
http://didkobravo.com/StyleSheets.html

14 Posted by Clint Priest on 28 February 2008 | Permalink

I found that this code works for dynamically inserting a tag with content:

var CSS = 'body { margin: 0px; }';
var htmDiv = document.createElement('div');
htmDiv.innerHTML = '<p>x</p><style>'+CSS+'</style>';
document.body.appendChild(htmDiv.childNodes[1]);

This works in both IE6 and IE7 as well as all the standards compliant browsers.

15 Posted by Kevin Thommes on 8 May 2008 | Permalink

This is slightly off topic but I was never able to add any styles using JavaScript in IE. A little background on what I wanted to do is to remove the indent of the bullets of a ul list but different values for styles are needed for IE and FF. Since we're able to add styles using JavaScript in FF, I decided to have a default style for IE and then use JavaScript to test if the browser is Netscape, if so then add the new styles for FF. These new styles would then overwrite my IE default. Here's some code:

head-tag
style-tag
ul {margin-left:15px; margin-top: 0} /* IE default */
ul li {padding-left: 5px;}
/style-tag

script-tag
// script to add FF style
if (navigator.appName == "Netscape") {
var stag = document.createElement('style');
stag.setAttribute("type", "text/css");
var sclass = 'td.errormsg ul {margin-left:-25px; margin-top: 0}';
sclass = document.createTextNode(sclass)
stag.appendChild(sclass);
document.getElementsByTagName('head')[0].appendChild(stag);
}
/script-tag
/head-tag