Peter
Peter

Reputation: 4057

Evaluation order of LINK and STYLE elements in HEAD

It appears to me that all modern browsers including recent versions of Chrome, Safari and FireFox (possibly since the beginning) respect the order of style and link elements in the head; even when created dynamically and added during run-time using JavaScript.

For example, here red.css and green.css both specify the body background color; the first sets the body background red, the second sets it green:

<head>
    <!-- other code -->
    <link rel="stylesheet" href="red.css" type="text/css">
    <link rel="stylesheet" href="green.css" type="text/css">
</head>

The result is that background color of the body is green since green.css is placed after red.css and evaluated afterwards.

The ordering of elements appears to hold true even when the link elements are created dynamically and inserted into the head. For instance, dynamically creating a link element that loads green.css will only set the body background color green if it is inserted after red.css.

However, the only browser that does not seem to respect this is Internet Explorer (at least IE 7-9 do not). It appears that with IE the most recently added link or style element is evaluated on-top everything that has already been evaluated; it does not respect the tree order when added during run-time.

Is respecting the order non-standard behavior, or is this an Internet Explorer bug? How can I fix this for Internet Explorer?

An idea I have come up with (that works) is to dynamically remove all existing link and style elements and add them back in the same tree order -- which is the order I wish them to be evaluated.

Any insight would be greatly appreciated.

UPDATE

Here is a more detailed code sample as requested:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="red.css" type="text/css"> <!-- sets red -->
</head>
<body>

<script type="text/javascript">

    setTimeout(function() {

        // IE7-8 does not support referencing document.head
        var head = document.getElementsByTagName("head")[0];

        var link = document.createElement("link");
        link.setAttribute("href", "green.css");
        link.setAttribute("rel", "stylesheet");
        link.setAttribute("type", "text/css");

        // All modern browesers will leave the background
        // color red, except IE will set it green.
        head.insertBefore(link, head.firstChild);

        // Now comment out the above line and try adding the link
        // using this instead. All modern browsers (including IE)
        // will set the body background color green after two seconds.
        // IE seems to always evaluate the last dynamically added link.

        // head.appendChild(link);

    }, 2000);

</script>

</body>
</html>

Contents of red.css:

body { background-color: red; }

Contents of green.css:

body { background-color: green; }

Upvotes: 4

Views: 604

Answers (3)

jfriend00
jfriend00

Reputation: 707328

You don't tell us the details of what problem you're really trying to solve by inserting stylesheets, but it is likely that there are simply better ways to solve the real problem instead of dynamically inserting a style sheet in a specific order in the list.

For example, you could have both stylesheets (slightly modified to key off another class) in place and via adding or removing a single class to the <body> tag, you could trigger a change from green to red or vice/versa.

Upvotes: 1

Oleg
Oleg

Reputation: 24988

What if, instead of re-appending stylesheets, you were to toggle an attribute of theirs that would force re-rendering? For instance, you could try iterating over all link/style elements, set their media attribute to none and then re-set it back to the original.

Upvotes: 3

zenkaty
zenkaty

Reputation: 1548

What you're referring to is CASCADING - a very important function of the way CASCADING style sheets (CSS) work. All browsers work this way, including IE. If they didn't cascade, it would be a major problem.

However, there are some styles that don't work in some versions of IE - perhaps what you're looking at, is styles not working properly, as opposed to the cascading not working properly. Would you like to post a specific example?

Upvotes: 0

Related Questions