Search code examples
javascriptperformancetwitter-bootstrapstylesheetbootswatch

Bootstrap / Bootswatch stylesheet changer that actually works


I'm trying to build dynamic CSS stylesheet changer, as simple as possible, for Bootstrap / Bootswatch. I've seen many sources, but I found that most examples relies on additional title attribute of link tag. And thus, doesn't work in all browsers or works wrong (mainly because of this problem).

I also noticed, that using title or rel="alternate stylesheet" isn't perfect idea, as though styles listed this way are "ignored" (not rendered) upon initial page load, they are somehow parsed, making browser unbelievable slow. I've added two or three Bootswatch styles next to default Bootstrap stylesheet and I nearly killed my Chrome, though page was rendered only with default styling.

Can someone show an example of dynamic stylesheet changer or proper use-case of title and rel="alternate stylesheet" attribute, that would not consume all my computer resources?


Solution

  • Turned out to be as simple as declaring "default" stylesheet using title attribute:

    <link href="assets/bootstrap/bootstrap.min.css" rel="stylesheet" media="screen" title="main">
    

    Then adding some links in form of list (can be used for building Bootstrap's dropdown):

    <ul class="dropdown-menu">
    
      <li><a href="#" class="change-style-menu-item" rel="assets/bootstrap/bootstrap.min.css"><i class="icon-fixed-width icon-pencil"></i> bootstrap.min.css (Default)</a></li>
    
      <li><a href="#" class="change-style-menu-item" rel="assets/bootstrap/bootstrap.cyborg.min.css"><i class="icon-fixed-width icon-pencil"></i> bootstrap.cyborg.min.css (Cyborg)</a></li>
    
    </ul>
    

    with rel attribute poining with full path to additional stylesheet.

    And then adding a very simple jQuery function:

    <script type="text/javascript">
    /*<![CDATA[*/
        jQuery(function($)
        {
            $('body').on('click', '.change-style-menu-item', function()
            {
                $('link[title="main"]').attr('href', $(this).attr('rel'));
            });
        });
    /*]]>*/
    </script>
    

    Works like a charm.

    If you have only one stylesheet in entire page, you can omit adding title attribute to link tag and "catch" it using simple $('link') selector instead of $('link[title="main"]'). Since I had other stylesheets included (bootstrap-responsive.min.css), referencing "changeable" stylesheet with title attribute was obligatory.