Question

I'm trying to make a live, in-page css editor with a preview function that would reload the stylesheet and apply it without needing to reload the page. What would be the best way to go about this?

Was it helpful?

Solution

On the "edit" page, instead of including your CSS in the normal way (with a <link> tag), write it all to a <style> tag. Editing the innerHTML property of that will automatically update the page, even without a round-trip to the server.

<style type="text/css" id="styles">
    p {
        color: #f0f;
    }
</style>

<textarea id="editor"></textarea>
<button id="preview">Preview</button>

The Javascript, using jQuery:

jQuery(function($) {
    var $ed = $('#editor')
      , $style = $('#styles')
      , $button = $('#preview')
    ;
    $ed.val($style.html());
    $button.click(function() {
        $style.html($ed.val());
        return false;
    });
});

And that should be it!

If you wanted to be really fancy, attach the function to the keydown on the textarea, though you could get some unwanted side-effects (the page would be changing constantly as you type)

Edit: tested and works (in Firefox 3.5, at least, though should be fine with other browsers). See demo here: http://jsbin.com/owapi

OTHER TIPS

Possibly not applicable for your situation, but here's the jQuery function I use for reloading external stylesheets:

/**
 * Forces a reload of all stylesheets by appending a unique query string
 * to each stylesheet URL.
 */
function reloadStylesheets() {
    var queryString = '?reload=' + new Date().getTime();
    $('link[rel="stylesheet"]').each(function () {
        this.href = this.href.replace(/\?.*|$/, queryString);
    });
}

There is absolutely no need to use jQuery for this. The following JavaScript function will reload all your CSS files:

function reloadCss()
{
    var links = document.getElementsByTagName("link");
    for (var cl in links)
    {
        var link = links[cl];
        if (link.rel === "stylesheet")
            link.href += "";
    }
}

Check out Andrew Davey's snazzy Vogue project - http://aboutcode.net/vogue/

One more jQuery solution

For a single stylesheet with id "css" try this:

$('#css').replaceWith('<link id="css" rel="stylesheet" href="css/main.css?t=' + Date.now() + '"></link>');

Wrap it in a function that has global scrope and you can use it from the Developer Console in Chrome or Firebug in Firefox:

var reloadCSS = function() {
  $('#css').replaceWith('<link id="css" rel="stylesheet" href="css/main.css?t=' + Date.now() + '"></link>');
};

A shorter version in Vanilla JS and in one line:

for (var link of document.querySelectorAll("link[rel=stylesheet]")) link.href = link.href.replace(/\?.*|$/, "?ts=" + new Date().getTime())

Or expanded:

for (var link of document.querySelectorAll("link[rel=stylesheet]")) {
  link.href = link.href.replace(/\?.*|$/, "?ts=" + new Date().getTime())
}

Based on previous solutions, I have created bookmark with JavaScript code:

javascript: { var toAppend = "trvhpqi=" + (new Date()).getTime(); var links = document.getElementsByTagName("link"); for (var i = 0; i < links.length;i++) { var link = links[i]; if (link.rel === "stylesheet") { if (link.href.indexOf("?") === -1) { link.href += "?" + toAppend; } else { if (link.href.indexOf("trvhpqi") === -1) { link.href += "&" + toAppend; } else { link.href = link.href.replace(/trvhpqi=\d{13}/, toAppend)} }; } } }; void(0);

Image from Firefox:

enter image description here

What does it do?

It reloads CSS by adding query string params (as solutions above):

Yes, reload the css tag. And remember to make the new url unique (usually by appending a random query parameter). I have code to do this but not with me right now. Will edit later...

edit: too late... harto and nickf beat me to it ;-)

i now have this:

    function swapStyleSheet() {
        var old = $('#pagestyle').attr('href');
        var newCss = $('#changeCss').attr('href');
        var sheet = newCss +Math.random(0,10);
        $('#pagestyle').attr('href',sheet);
        $('#profile').attr('href',old);
        }
    $("#changeCss").on("click", function(event) { 
        swapStyleSheet();
    } );

make any element in your page with id changeCss with a href attribute with the new css url in it. and a link element with the starting css:

<link id="pagestyle" rel="stylesheet" type="text/css" href="css1.css?t=" />

<img src="click.jpg" id="changeCss" href="css2.css?t=">

Another answer: There's a bookmarklet called ReCSS. I haven't used it extensively, but seems to work.

There's a bookmarklet on that page to drag and drop onto your address bar (Can't seem to make one here). In case that's broke, here's the code:

javascript:void(function()%7Bvar%20i,a,s;a=document.getElementsByTagName('link');for(i=0;i%3Ca.length;i++)%7Bs=a[i];if(s.rel.toLowerCase().indexOf('stylesheet')%3E=0&&s.href)%20%7Bvar%20h=s.href.replace(/(&%7C%5C?)forceReload=%5Cd%20/,'');s.href=h%20(h.indexOf('?')%3E=0?'&':'?')%20'forceReload='%20(new%20Date().valueOf())%7D%7D%7D)();

In a simple manner you can use rel="reload" instead of rel="stylesheet" .

<link rel="preload" href="path/to/mystylesheet.css" as="style" onload="this.rel='stylesheet'">

simple if u are using php Just append the current time at the end of the css like

<link href="css/name.css?<?php echo 
time(); ?>" rel="stylesheet">

So now everytime u reload whatever it is , the time changes and browser thinks its a different file since the last bit keeps changing.... U can do this for any file u force the browser to always refresh using whatever scripting language u want

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top