How to create a – Spooky Apr 24 '15 at 21:20

  • This code did not work for me. I crafted some much shorter code that works in three browsers and will post my answer here. – David Spector Dec 04 '18 at 14:46
  • I couldn't figure out why Chrome wasn't updating my styles when I added a style block to the head dynamically. I tried this and magically it updates. I need to investigate what actually is the difference here in this code that triggers the browser to re-render the css. But, big thanks! – prograhammer Apr 01 '19 at 10:58
  • 6

    Here is a variant for dynamically adding a class

    function setClassStyle(class_name, css) {
      var style_sheet = document.createElement('style');
      if (style_sheet) {
        style_sheet.setAttribute('type', 'text/css');
        var cstr = '.' + class_name + ' {' + css + '}';
        var rules = document.createTextNode(cstr);
        if(style_sheet.styleSheet){// IE
          style_sheet.styleSheet.cssText = rules.nodeValue;
        } else {
          style_sheet.appendChild(rules);
        }
        var head = document.getElementsByTagName('head')[0];
        if (head) {
          head.appendChild(style_sheet);
        }
      }
    }
    
    iandotkelly
    • 9,024
    • 8
    • 48
    • 67
    Michael
    • 69
    • 1
    • 1
    5

    All good, but for styleNode.cssText to work in IE6 with node created by javascipt, you need to append the node to the document before you set the cssText;

    further info @ http://msdn.microsoft.com/en-us/library/ms533698%28VS.85%29.aspx

    Tony
    • 51
    • 1
    • 1
    5

    This object variable will append style tag to the head tag with type attribute and one simple transition rule inside that matches every single id/class/element. Feel free to modify content property and inject as many rules as you need. Just make sure that css rules inside content remain in one line (or 'escape' each new line, if You prefer so).

    var script = {
    
      type: 'text/css', style: document.createElement('style'), 
      content: "* { transition: all 220ms cubic-bezier(0.390, 0.575, 0.565, 1.000); }",
      append: function() {
    
        this.style.type = this.type;
        this.style.appendChild(document.createTextNode(this.content));
        document.head.appendChild(this.style);
    
    }}; script.append();
    
    Spooky
    • 1,235
    • 15
    • 17
    • 1
      I liked this solution, so I used it myself to change button sizes on mobile devices, but it is incorrect that the content property needs to be on one line: Simply concatenate multiple strings (over multiple lines) with the + operator. – RufusVS Feb 27 '18 at 21:07
    • True. I know and I knew that. But, sometimes, I am just too lazy to write as I am supposed to. :D Cheers. – Spooky Oct 11 '19 at 17:41
    5

    You wrote:

    var divNode = document.createElement("div");
    divNode.innerHTML = "<br><style>h1 { background: red; }</style>";
    document.body.appendChild(divNode);
    

    Why not this?

    var styleNode = document.createElement("style");
    document.head.appendChild(styleNode);
    

    Henceforward you can append CSS rules easily to the HTML code:

    styleNode.innerHTML = "h1 { background: red; }\n";
    styleNode.innerHTML += "h2 { background: green; }\n";
    

    ...or directly to the DOM:

    styleNode.sheet.insertRule("h1 { background: red; }");
    styleNode.sheet.insertRule("h2 { background: green; }");
    

    I expect this to work everywhere except archaic browsers.

    Definitely works in Chrome in year 2019.

    7vujy0f0hy
    • 8,741
    • 1
    • 28
    • 33
    3

    This function will inject css whenever you call the function appendStyle like this:
    appendStyle('css you want to inject')

    This works by injecting a style node into the head of the document. This is a similar technique to what is commonly used to lazy-load JavaScript. It works consistently in most modern browsers.

    appendStyle = function (content) {
      style = document.createElement('STYLE');
      style.type = 'text/css';
      style.appendChild(document.createTextNode(content));
      document.head.appendChild(style);
    }
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
      <h1>Lorem Ipsum</h1>
      <p>dolar sit amet</p>
      <button onclick='appendStyle("body { background-color: #ff0000;}h1 { font-family: Helvetica, sans-serif; font-variant: small-caps; letter-spacing: 3px; color: #ff0000; background-color: #000000;}p { font-family: Georgia, serif; font-size: 14px; font-style: normal; font-weight: normal; color: #000000; background-color: #ffff00;}")'>Press me to inject CSS!</button>
    </body>
    
    </html>

    You can also lazy-load external CSS files by using the following snippet:

    appendExternalStyle = function (content) {
      link = document.createElement('LINK');
      link.rel = 'stylesheet';
      link.href = content;
      link.type = 'text/css';
      document.head.appendChild(link);
    }
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <style>
        html {
          font-family: sans-serif;
          font-display: swap;
        }
      </style>
    </head>
    
    <body>
    
      <h1>Lorem Ipsum</h1>
      <p>dolar sit amet</p>
      <button onclick='appendExternalStyle("data:text/css;base64,OjotbW96LXNlbGVjdGlvbntjb2xvcjojZmZmIWltcG9ydGFudDtiYWNrZ3JvdW5kOiMwMDB9OjpzZWxlY3Rpb257Y29sb3I6I2ZmZiFpbXBvcnRhbnQ7YmFja2dyb3VuZDojMDAwfWgxe2ZvbnQtc2l6ZToyZW19Ym9keSxodG1se2NvbG9yOnJnYmEoMCwwLDAsLjc1KTtmb250LXNpemU6MTZweDtmb250LWZhbWlseTpMYXRvLEhlbHZldGljYSBOZXVlLEhlbHZldGljYSxzYW5zLXNlcmlmO2xpbmUtaGVpZ2h0OjEuNjd9YnV0dG9uLGlucHV0e292ZXJmbG93OnZpc2libGV9YnV0dG9uLHNlbGVjdHstd2Via2l0LXRyYW5zaXRpb24tZHVyYXRpb246LjFzO3RyYW5zaXRpb24tZHVyYXRpb246LjFzfQ==")'>press me to inject css!</button>
    </body>
    
    </html>
    Joel Ellis
    • 1,332
    • 1
    • 12
    • 31
    • This is roughly the approach that I developed independently. Short and sweet and works in the latest Firefox, Microsoft Edge, and Chrome browsers. Of course, there are too many JavaScript errors in Internet Explorer to worry about including it in browser compatibility anymore. – David Spector Dec 04 '18 at 14:51
    2

    as i know there are 4 ways to do that.

    var style= document.createElement("style");
    (document.head || document.documentElement).appendChild(style);
    var rule=':visited {    color: rgb(233, 106, 106) !important;}';
    
    //no 1
    style.innerHTML = rule;
    //no 2
    style.appendChild(document.createTextNode(rule));
    
    //no 3 limited with one group
    style.sheet.insertRule(rule);
    //no 4 limited too
    document.styleSheets[0].insertRule('strong { color: red; }');
    
    //addon
    style.sheet.cssRules //list all style
    stylesheet.deleteRule(0)  //delete first rule
    
    
    defend orca
    • 617
    • 7
    • 17
    1

    If the problem you're facing is injecting a string of CSS into a page it is easier to do this with the <link> element than the <style> element.

    The following adds p { color: green; } rule to the page.

    <link rel="stylesheet" type="text/css" href="data:text/css;charset=UTF-8,p%20%7B%20color%3A%20green%3B%20%7D" />
    

    You can create this in JavaScript simply by URL encoding your string of CSS and adding it the HREF attribute. Much simpler than all the quirks of <style> elements or directly accessing stylesheets.

    let linkElement: HTMLLinkElement = this.document.createElement('link');
    linkElement.setAttribute('rel', 'stylesheet');
    linkElement.setAttribute('type', 'text/css');
    linkElement.setAttribute('href', 'data:text/css;charset=UTF-8,' + encodeURIComponent(myStringOfstyles));
    

    This will work in IE 5.5 upwards

    moefinley
    • 1,248
    • 1
    • 13
    • 26
    0

    Anyone who is looking for Typescript version,

    const addStyles = (styles) => {
      let styleNode : HTMLStyleElement = document.createElement('style'); 
      styleNode.type = 'text/css'; 
      if (styleNode.style)  
        styleNode.style.cssText = styles; 
      else  
        styleNode.appendChild(document.createTextNode(styles)); 
            
      /* Append style to the head element */ 
      document.head.appendChild(styleNode);  
    }
    

    Also, in react/vue/angular if direct injection of CSS is needed, you can use posstcss-js to convert CSS into JSS and use CSS-in-JSS to inject a new styleSheet directly. For more info, please follow this documentation.

    Update

    You can use document.head as well as per @Brandon McConnell's comment.

    Shujath
    • 846
    • 1
    • 8
    • 22
    0

    The most trival answer:

    function addStyle (styleText) {
      const styleNode = document.createElement('style'); 
      styleNode.type = 'text/css'; 
      styleNode.textContent = styleText;
      document.documentElement.appendChild(styleNode);  
      return styleNode;
    }
    
    Chester Fung
    • 182
    • 1
    • 10
    0

    I'm used to using this

    function createElement(_type,code) {
      let s = document.createElement(_type);
      s.appendChild(document.createTextNode(code));
      document.body.appendChild(s);
    }
    createElement('style','body{background: red}') // <style> code </style>
    createElement('script','console.log("work")') // <script> code </script>
    perona chan
    • 101
    • 1
    • 8
    -3
    this link may helpful to you: 
    

    http://jonraasch.com/blog/javascript-style-node

    Vinod Poorma
    • 419
    • 1
    • 6
    • 15
    • 2
      Please don’t use preformatted text/code blocks for a short paragraph. Linking for an answer this way is also useless. Please summarize the website first. –  Apr 19 '20 at 08:48