Applying stylesheets dynamically with jQuery

jquery logoA colleague of mine asked me how to apply a stylesheet to a web page dynamically using jQuery and I had never done such a thing but my first thought was that is must be pretty simple. I've spent a lot of time thinking of so many things other than web et. al. so it was nice to delve into some of that stuff again. Check out the live demo

As we know stylesheets are defined in the head section of an html file like this

<html>
    <head>
        <link rel="stylesheet" href="stylesheet.css" type="text/css" />
    head>
    <body>
    ...
html>

Now, say that we want to apply another stylesheet dynamically after the fact, so to speak, triggered by some event. This could be a button click or some other arbitrary event that is triggered. So, what we want to do is simply insert a new element into the head section of the page DOM. This can be done in a couple of lines of jQuery:

$(document).ready(function () {
    $("a").click(function () {
        $('head').append('');
    });
});

The key is at what time we add the link to the style sheet. The first line in the code above repeated here asserts that the DOM is ready for manipulation.

$(document).ready(function () {
    //...
});

The second part repeated here adds a click event to all hyperlinks in the page.

$("a").click(function() { //...

And the very task is performed by the last piece of code where the head element is appended with a new link element.

$('head').append('');

Comments (14) -

  • Jonas

    2008-09-09 10:29:17 | Reply

    Nice example, although I would personally prefer using something like either:

    ...
    $('head > link').filter(':first').attr('href', 'something.css');
    ...


    or

    ...
    $('head > link').filter(':first').replaceWith('');
    ...


    Mainly since your code just appends a new element to the DOM every time the link is clicked, without regard to the old one. Of course, these examples imply that a single is used, but using jQuery selectors it would be quite easy to make it a bit "smarter".

  • Rickard

    2008-09-16 07:38:39 | Reply

    You're right, my attempt was at a very basic level, at best. However, just as intended. I like your first solution in particular but the requirements for the demo was that I needed to apply a second style sheet dynamically. Yours is replacing the first style sheet in the page.

    I agree that jQuery selectors makes it a whole lot easier and I'm planning another post with a more 'real-like' implementation.

  • club penguin cheats

    2009-07-09 07:37:17 | Reply

    Mainly since your code just appends a new element to the DOM every time the link is clicked, without regard to the old one. Of course, these examples imply that a single is used, but using jQuery selectors it would be quite easy to make it a bit "smarter".

  • Eugene Kerner

    2014-02-09 01:07:55 | Reply

    Note that IE doesn't seem to like like attr() on this one ...

    // works in FF and IE ...
    $('head').append('');

    // works in FF and IE ...
    $('').appendTo($('head'));

    // works in FF but not IE ...
    $('').attr({
    rel : 'stylesheet',
    type : 'text/css',
    href : '/shared/css/screen.css.php?width=' + screen.width + '&height=' + screen.height
    }).appendTo($('head'));

    // works in FF but not IE ...
    $('head').append(
    $(document.createElement('link')).attr({
    rel : 'stylesheet',
    type : 'text/css',
    href : '/shared/css/screen.css.php?width=' + screen.width + '&height=' + screen.height
    })
    );

    // works in FF but not IE ...
    $(document.createElement('link')).attr({
    rel : 'stylesheet',
    type : 'text/css',
    href : '/shared/css/screen.css.php?width=' + screen.width + '&height=' + screen.height
    }).appendTo(document.getElementsByTagName('head')[0]);

  • afaoiu

    2014-02-09 01:17:53 | Reply

    doesn't work in IE7

  • John

    2014-02-09 01:18:15 | Reply

    Thanks for the post. Just what I needed for my script

    • Daniel

      2014-02-09 01:18:57 | Reply

      That's what I looked for, I am going to try it.
      But, is there as well a way to remove the added css dynamically?

  • calvin

    2014-02-09 01:19:58 | Reply

    Thanks I have used this to create a default style switcher for my JQuery mobile application using localStorage and html5 ! Test it on your mobile or tablet here http://cambs.eu/mobile/

  • Poole Web Design

    2014-02-09 01:20:33 | Reply

    This works absolutely fine for me! But how would you also add a class to the body tag? Would you have to wrap it up in a function? Thoughts would be really appreciated!

    • Rickard

      2014-02-09 01:21:16 | Reply

      I would do something like:

      $("body").addClass("foo");

      You don't have to wrap it in a function but I prefer packaging much of my JavaScript code in either closure scope or in jQuery plugins. See rickardnilsson.net/.../...itching-stylesheets.aspx for more info.

  • Stan

    2014-02-09 01:21:47 | Reply

    Nice...used this to dynamically add a css stylesheet for when there was no css3 border-radius support...had it in the page, but the image references got too hairy since it's a facebook app http://apps.facebook.com/mytopslist (it's in an iframe) and you have to keep the image references relative so people can also access the https version...also I went to login via facebook below, but i got an error (maybe your plugin needs to be updated?)

  • vinod

    2014-02-09 01:22:07 | Reply

    I tricked like this , i have link tag in header instead of append used html that work in both browser's IE8 and FF
    and other way is change the link attribute href with our stylesheet name,
    $(document).ready(function() {
    $(window).resize(function() {
    var winwdith = $(window).width();
    // This will fire each time the window is resized:
    if(winwdith >= 800) {
    // if larger or equal
    //alert(winwith);
    //$('head').html('');
    $('link').attr('href','ggcss.css');
    } else {
    //alert(winwith);
    // if smaller
    //$('head').html('');
    $('link').attr('href','ggmcss.css');
    }
    }).resize();
    });
    jQuery Have Fun

  • ranadheer

    2014-02-09 01:23:14 | Reply

    To add stylesheet dynamically read this : coding-issues.blogspot.in/.../...heet-of-page.html

  • Hasse

    2014-02-09 01:23:39 | Reply

    Doesn't that trigger a complete rerendering of the entire page, since the head section is closed at insertion time?
    (and if yes, is there any way to avoid that, if the new sheet is only affecting a minor part of a huge page?) :-/

Loading
Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.