Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use CSSStyleSheet.insertRule() properly?

I can't figure out where I'm going wrong here :/. When I run this code, all I get is a blank element. I can't seem to get the insertRule method to do anything (not even produce an error). Am I missing something?

<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
</head>
<body>
<script>
    var sheet = (function() {
        // Create the <style> tag
        var style = document.createElement("style");

        // WebKit hack
        style.appendChild(document.createTextNode(""));

        // Add the <style> element to the page
        document.head.appendChild(style);

        return style.sheet;
    })();
    sheet.insertRule("\
        #gridContainer {\
            width: 100%;\
            height: 100%;\
        }\
    ", 0);
</script>
</body>
</html>
like image 225
klinore Avatar asked Mar 08 '15 19:03

klinore


2 Answers

It is slightly confusing but your code does actually work, it is just that you can't see the inserted rules in the XML tree returned.

To verify that your code works, there are two tests you can do:

var style = (function() {
    // Create the <style> tag
    var style = document.createElement("style");

    // WebKit hack
    style.appendChild(document.createTextNode(""));

    // Add the <style> element to the page
    document.head.appendChild(style);
  
    console.log(style.sheet.cssRules); // length is 0, and no rules

    return style;
})();
style.sheet.insertRule('.foo{color:red;}', 0);
console.log(style.sheet.cssRules); // length is 1, rule added
<p class="foo">
  I am some text
</p>

Run the above snippet, and you can see that the CSS rule does apply. And the cssRules property changes as well in the console.

This is often noted when browser extensions generate custom style-sheets appended to the DOM, and while debugging they appear as empty style-sheets in the inspector.

like image 125
user3459110 Avatar answered Nov 10 '22 20:11

user3459110


This version is based on Awal's answer and Totally Pwn CSS with Javascript from web archive. The id parameter is useful for accesing the styleSheet with getElementById, and the media parameter is optinal and defauts to 'screen'. I am returning the styleSheet.sheet, this is just my preference.

function createStyleSheet (id, media) {
    var el   = document.createElement('style');
    // WebKit hack
    el.appendChild(document.createTextNode(''));
    el.type  = 'text/css';
    el.rel   = 'stylesheet';
    el.media = media || 'screen';
    el.id    = id;
    document.head.appendChild(el);
    return el.sheet;
}
like image 21
Jorge Gonzalez Avatar answered Nov 10 '22 21:11

Jorge Gonzalez