Dynamically Load Stylesheets Using MooTools 1.2

By  on  

Theming has become a big part of the Web 2.0 revolution. Luckily, so too has a higher regard for semantics and CSS standards. If you build your pages using good XHTML code, changing a CSS file can make your website look completely different. Using a short MooTools snippet, you can dynamically load a change primary stylesheets with just one click.

Step 1: The XHTML

<p>
<a href="?theme=black" class="load-css" rel="load-stylesheet/black.css">Load Black Stylesheet</a><br /><br />
<a href="?theme=red" class="load-css" rel="load-stylesheet/red.css">Load Red Stylesheet</a><br /><br />
<a href="?theme=blue" class="load-css" rel="load-stylesheet/blue.css">Load Blue Stylesheet</a><br /><br />
</p>

Above are three links to three themes. The load-css class is added and the rel attribute holds the path to the CSS file for the sake of MooTools. If the user doesn't have JavaScript, I've added an href attribute to allow for the page to change the theme using server-side methods upon a new page load.

Step 2: The CSS

/* black.css */
body { background:#000; color:#fff; }
a		{ color:#ccc; }

/* blue.css */
body { background:#00f; color:#fff; }
a		{ color:#fff; }

/* red.css */
body { background:#f00; color:#fff; }
a		{ color:#fff; }

Above you see the contents of three stylesheet files. These can act as three different themes, so to speak.

Step 3: The MooTools JavaScript

window.addEvent('domready', function () {
	//for every anchor with the class "load-css"...
		$$('.load-css').each(function(el) {
			//add a click  event to add the stylesheet
			el.addEvent('click', function() {
			//get the file. file is based on the anchor's rel attribute
			var css = new Asset.css(el.get('rel'), { });
		});
	});
});

The MooTools JavaScript snippet is very simple. For every link with the load-css class, a click event listener is added to load the specified stylesheet. Once a stylesheet has been injected into the page, no more file calls are made -- once it's loaded, it's loaded.

Recent Features

  • By
    CSS Gradients

    With CSS border-radius, I showed you how CSS can bridge the gap between design and development by adding rounded corners to elements.  CSS gradients are another step in that direction.  Now that CSS gradients are supported in Internet Explorer 8+, Firefox, Safari, and Chrome...

  • By
    Facebook Open Graph META Tags

    It's no secret that Facebook has become a major traffic driver for all types of websites.  Nowadays even large corporations steer consumers toward their Facebook pages instead of the corporate websites directly.  And of course there are Facebook "Like" and "Recommend" widgets on every website.  One...

Incredible Demos

  • By
    New MooTools Plugin:  ElementFilter

    My new MooTools plugin, ElementFilter, provides a great way for you to allow users to search through the text of any mix of elements. Simply provide a text input box and ElementFilter does the rest of the work. The XHTML I've used a list for this example...

  • By
    Vibration API

    Many of the new APIs provided to us by browser vendors are more targeted toward the mobile user than the desktop user.  One of those simple APIs the Vibration API.  The Vibration API allows developers to direct the device, using JavaScript, to vibrate in...

Discussion

  1. Cool! :)

  2. This is something that I can see myself getting a lot of use out of. I’ve always wondered how to do this so I’ll definitely check it out.

  3. Ambarita

    Is it possible to implement a hash-cookie processing where user can save his/her theme selection via cookie?

  4. @Ambarita: Absolutely. You can see something like by reading this article:

    http://davidwalsh.name/save-text-size-preference-mootools-12

  5. Wow, thanks for that. I’ll use that for my site, it’s nice to be able to do that so easily with Mootools.

  6. Greg

    Poor write up.

    You should really show how to modify your code to actually make it useful for those who don’t know xhtml or java scripting.

    Or at the very least provide some sort of direction for readers to impliment this.

    -Greg

  7. @Greg: My blog is for Web Developers that have a basic knowledge of XHTML and javascript. Those looking for a magic wand wont find one here.

  8. Wouldn’t the stylesheets have to be exact overlays of each other? Meaning that they all specify exactly the same attributes? Otherwise, you would end up with remnants of your previous stylesheet when you apply the new one. No?

  9. @Matthew: Yes, but if you planned to use a system like this, you’d keep that in mind. I’d recommend one “structure” CSS file and many “theme” CSS files.

  10. This, like so much in MooTools is very nice, however I have a problem with the use of class and rel attributes.

    For me this would work without mis-use of attributes if each stylesheet theme link had a different id attribute
    and the rel attribute was not specified.

    ie

    var css = new Asset.css(el.get('id'), { }); 
    
  11. Is there a way to make a fading transition to another stylesheet? :)

  12. Indeed can be great to have a fading effect, with a listener for the day time you can for example use a fade transition from a day css to a night css :) i love this idea..

    Anyway don’t really know why but this code doesn’t work for me.. i use it with the last version of MooTools and change $$ by document.search() but still doesn’t work.

    Strange thing, the click load the true link, I’m pretty sure my code is good implemented..

    css and js folders are on the same level in my folder architecture.

    HTML :

    <a href="" rel="nofollow">DAY</a>
    

    JS in the header just to be sure :

    window.addEvent('domready', function () {
    	//for every anchor with the class "load-css"...
    		document.search('.load-css').each(function(el) {
    			//add a click  event to add the stylesheet
    			el.addEvent('click', function() {
    			//get the file. file is based on the anchor's rel attribute
    			var css = new Asset.css(el.get('rel'), { });
    		});
    	});
    });
    

    If you have any idea.. Thank you for this blog it rocks :)

  13. Hi,

    Thx for your great blog, mooTools rocks and you rocks too :)

    For now, I try to implement the same thing but for an Iframe that is created from mooTools… I dont know how to assign the stylesheet to my IFrame (which source is about:blank) from the script that create this IFrame…

    If you have an idea, that would greatly help me, cause I really dont know by where I must start, I found no parameter for designate the document that receive the stylesheet…

    And sorry for my bad english…

    And again, big up for your blog, you rocks !

  14. Found a solution :

    var css = new Element('link', { type: 'text/css', rel: 'stylesheet', href: 'styles.css' });
    css.inject(myFrame.contentWindow.document.body, 'top');
    

    but even cant find a solution to work with asset… And it makes me a problem : the css link is in the body tag, not in head… But I dont know how to access head of my IFrame to inject my css link… If anyone have an idea…

  15. var css = new Element('link', { type: 'text/css', rel: 'stylesheet', href: 'editeur.css' });
    css.inject(myFrame.contentWindow.document.getElementsByTagName("head")[0]);
    

    It’s ok on FireFox but I eared it doesnt work on IE (but not tested)… I’ve search for a long time how to access head tag with mootools (wich is better cross browser than my previous uggly code !) but I’ve failed… Perhaps it doesnt exist ? Anyway, that work for me with FF, that was my mainly goal !

  16. Great stylesheet switcher. I use it for my print and large text versions of pages and it works great.

    But…I’m switching my CSS scheme to have a core stylesheet and then supplemental stylesheets for different sections of the site. Is there a way to have the “rel” attribute on tags define 2 stylesheets?

    I need another stylesheet when loading from this link (wsm_feature.css) following the wsm_core.css:

    Return to web page

  17. Thanks for information! =)

  18. I’d use $(body).toggleClass('enlarge'); and then write css rules as

    body p{
       font-size:12px;
    }
    
    body,enlarge p{
       font-size:16px;
    }
    

    Now you don’t have to reload css files and have all the css in one file too.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!