Internet Explorer stylesheet inject glitch

by Developer @ pebbl.co.uk on Monday, 27 June 2011

:: This doesn't work in IE... 8???

One more random glitch to appear out of nowhere, I guess it just goes to show how much more front-end work I've been doing recently :) Even though today's browsers are much more converged than their forerunners, there is still a veritable selection of quirks that need to be kept in mind.

For example, If you are having problems with IE7/IE8/IE9 when trying to inject a stylesheet link tag in to the DOM (either in the head or body of a HTML page), then look no further than this post - unless of course this doesn't solve your problem, in which case you are free to carry on googling.

:: The Problem

I was going in circles last night working on my new site, trying to get my JavaScript enhanced css to work in Internet Explorer 8. On top of some bespoke code to determin certain things about the current user agent, I was using jQuery to append conditionally chosen stylesheets to my DOM. Everything was fine in FF, Safari, Opera and Chrome - but IE refused to import my "core-ie.css".

Here is the offending line:

$('head').append(
   '<link rel="stylesheet" type="text/css" href="css/core-ie.css" />'
);

Now I know I've used the above construction before, and it has worked fine in IE. And as any programmer knows, there is nothing more frustrating than something that "should be working". So I went round in circles debugging, inspecting, tracing and alerting only to find what I already knew to be the truth - jQuery and my bespoke code were pretty much 99.8% cross-browser and everything I was asking for was actually happening. i.e. my link element was being injected in to the DOM. (Don't be fooled by IE8's inspector, it refused to display the added link element at any time - I resorted to alerting out the innerHTML of the head to discover the truth).

So the link tag was definitely being inserted in exactly the way I wanted... it was just being totally ignored for some reason? Now obviously at this step I thought maybe the problem resided in my CSS, maybe the style alterations I wanted were being overriden. So - as you would expect - I changed the CSS content to hide all child elements, and highlighted the body with a bright pink background and dotted orange border. No way that could be missed ;)

Much to my annoyance, this too was utterly ignored. So an exasperated then, and many googled variations on the theme of "append stylesheet jQuery IE8 problem" later; I came across one little comment (on a little page) that totally sorted my problem out... and probably could have been explained here in about 5 lines; that is if I didn't like to waffle.

:: The Solution

I do not know which versions of IE are specifically affected - I haven't had time to test and find out, but it seems that when using .innerHTML (that good old js property which jQuery makes good use of) IE will treat paths for certain elements as absolute URLs - even if they are quite obviously relative.

So that solution I mentioned before? Well there's two - and now you know what is actually causing the problem they should both be straight-forward.

  1. Don't use relative paths on link elements when injecting them via innerHTML
  2. ... or ... Don't inject link elements using innerHTML, create them using createElement and append them properly to the DOM.
function loadStylesheet( href ){
   var ss = document.createElement('link');
       ss.type = 'text/css';
       ss.rel = 'stylesheet';
       ss.href = href;
   document.getElementsByTagName('head')[0].appendChild(ss);
}

Leave your comment