[javascript] How to create a <style> tag with Javascript?

I'm looking for a way to insert a <style> tag into an HTML page with JavaScript.

The best way I found so far:

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

This works in Firefox, Opera and Internet Explorer but not in Google Chrome. Also it's a bit ugly with the <br> in front for IE.

Does anyone know of a way to create a <style> tag that

  1. Is nicer

  2. Works with Chrome?

Or maybe

  1. This is a non-standard thing I should avoid

  2. Three working browsers are great and who uses Chrome anyway?

This question is related to javascript html css

The answer is


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();

I'm assuming that you're wanting to insert a style tag versus a link tag (referencing an external CSS), so that's what the following example does:

<html>
 <head>
  <title>Example Page</title>
 </head>
 <body>
  <span>
   This is styled dynamically via JavaScript.
  </span>
 </body>
 <script type="text/javascript">
   var styleNode = document.createElement('style');
   styleNode.type = "text/css";
   // browser detection (based on prototype.js)
   if(!!(window.attachEvent && !window.opera)) {
        styleNode.styleSheet.cssText = 'span { color: rgb(255, 0, 0); }';
   } else {
        var styleText = document.createTextNode('span { color: rgb(255, 0, 0); } ');
        styleNode.appendChild(styleText);
   }
   document.getElementsByTagName('head')[0].appendChild(styleNode);
 </script>
</html>

Also, I noticed in your question that you are using innerHTML. This is actually a non-standard way of inserting data into a page. The best practice is to create a text node and append it to another element node.

With respect to your final question, you're going to hear some people say that your work should work across all of the browsers. It all depends on your audience. If no one in your audience is using Chrome, then don't sweat it; however, if you're looking to reach the biggest audience possible, then it's best to support all major A-grade browsers


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


<style> tags should be places within the <head> element, and each added tag should be added to the bottom of the <head> tag.

Using insertAdjacentHTML to inject a style tag into the document head tag:

Native DOM:

_x000D_
_x000D_
document.head.insertAdjacentHTML("beforeend", `<style>body{background:red}</style>`)
_x000D_
_x000D_
_x000D_


jQuery:

_x000D_
_x000D_
$('<style>').text("body{background:red}").appendTo(document.head)
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
_x000D_
_x000D_
_x000D_


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


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


An example that works and are compliant with all browsers :

var ss = document.createElement("link");
ss.type = "text/css";
ss.rel = "stylesheet";
ss.href = "style.css";
document.getElementsByTagName("head")[0].appendChild(ss);

Here's a script which adds IE-style createStyleSheet() and addRule() methods to browsers which don't have them:

if(typeof document.createStyleSheet === 'undefined') {
    document.createStyleSheet = (function() {
        function createStyleSheet(href) {
            if(typeof href !== 'undefined') {
                var element = document.createElement('link');
                element.type = 'text/css';
                element.rel = 'stylesheet';
                element.href = href;
            }
            else {
                var element = document.createElement('style');
                element.type = 'text/css';
            }

            document.getElementsByTagName('head')[0].appendChild(element);
            var sheet = document.styleSheets[document.styleSheets.length - 1];

            if(typeof sheet.addRule === 'undefined')
                sheet.addRule = addRule;

            if(typeof sheet.removeRule === 'undefined')
                sheet.removeRule = sheet.deleteRule;

            return sheet;
        }

        function addRule(selectorText, cssText, index) {
            if(typeof index === 'undefined')
                index = this.cssRules.length;

            this.insertRule(selectorText + ' {' + cssText + '}', index);
        }

        return createStyleSheet;
    })();
}

You can add external files via

document.createStyleSheet('foo.css');

and dynamically create rules via

var sheet = document.createStyleSheet();
sheet.addRule('h1', 'background: red;');

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.


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);
    }
  }
}

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.

_x000D_
_x000D_
appendStyle = function (content) {_x000D_
  style = document.createElement('STYLE');_x000D_
  style.type = 'text/css';_x000D_
  style.appendChild(document.createTextNode(content));_x000D_
  document.head.appendChild(style);_x000D_
}
_x000D_
<!DOCTYPE html>_x000D_
<html lang="en">_x000D_
_x000D_
<head>_x000D_
  <meta charset="UTF-8">_x000D_
  <meta name="viewport" content="width=device-width, initial-scale=1.0">_x000D_
</head>_x000D_
<body>_x000D_
  <h1>Lorem Ipsum</h1>_x000D_
  <p>dolar sit amet</p>_x000D_
  <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>_x000D_
</body>_x000D_
_x000D_
</html>
_x000D_
_x000D_
_x000D_

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

_x000D_
_x000D_
appendExternalStyle = function (content) {_x000D_
  link = document.createElement('LINK');_x000D_
  link.rel = 'stylesheet';_x000D_
  link.href = content;_x000D_
  link.type = 'text/css';_x000D_
  document.head.appendChild(link);_x000D_
}
_x000D_
<!DOCTYPE html>_x000D_
<html lang="en">_x000D_
_x000D_
<head>_x000D_
  <meta charset="UTF-8">_x000D_
  <meta name="viewport" content="width=device-width, initial-scale=1.0">_x000D_
  <style>_x000D_
    html {_x000D_
      font-family: sans-serif;_x000D_
      font-display: swap;_x000D_
    }_x000D_
  </style>_x000D_
</head>_x000D_
_x000D_
<body>_x000D_
_x000D_
  <h1>Lorem Ipsum</h1>_x000D_
  <p>dolar sit amet</p>_x000D_
  <button onclick='appendExternalStyle("data:text/css;base64,OjotbW96LXNlbGVjdGlvbntjb2xvcjojZmZmIWltcG9ydGFudDtiYWNrZ3JvdW5kOiMwMDB9OjpzZWxlY3Rpb257Y29sb3I6I2ZmZiFpbXBvcnRhbnQ7YmFja2dyb3VuZDojMDAwfWgxe2ZvbnQtc2l6ZToyZW19Ym9keSxodG1se2NvbG9yOnJnYmEoMCwwLDAsLjc1KTtmb250LXNpemU6MTZweDtmb250LWZhbWlseTpMYXRvLEhlbHZldGljYSBOZXVlLEhlbHZldGljYSxzYW5zLXNlcmlmO2xpbmUtaGVpZ2h0OjEuNjd9YnV0dG9uLGlucHV0e292ZXJmbG93OnZpc2libGV9YnV0dG9uLHNlbGVjdHstd2Via2l0LXRyYW5zaXRpb24tZHVyYXRpb246LjFzO3RyYW5zaXRpb24tZHVyYXRpb246LjFzfQ==")'>press me to inject css!</button>_x000D_
</body>_x000D_
_x000D_
</html>
_x000D_
_x000D_
_x000D_


_x000D_
_x000D_
document.head.innerHTML += `_x000D_
  <style>_x000D_
    h1 {_x000D_
      color: red; _x000D_
    }_x000D_
    p {_x000D_
      color: blue;_x000D_
    }_x000D_
  </style>`
_x000D_
<h1>I'm red!</h1>_x000D_
<p>I'm blue!</p>
_x000D_
_x000D_
_x000D_

By far the most straightforward solution. All you have to do is type the same as how you'd normally declare style tags, between the backticks


Oftentimes there's a need to override existing rules, so appending new styles to the HEAD doesn't work in every case.

I came up with this simple function that summarizes all not valid "append to the BODY" approaches and is just more convenient to use and debug (IE8+).

window.injectCSS = (function(doc){
    // wrapper for all injected styles and temp el to create them
    var wrap = doc.createElement('div');
    var temp = doc.createElement('div');
    // rules like "a {color: red}" etc.
    return function (cssRules) {
        // append wrapper to the body on the first call
        if (!wrap.id) {
            wrap.id = 'injected-css';
            wrap.style.display = 'none';
            doc.body.appendChild(wrap);
        }
        // <br> for IE: http://goo.gl/vLY4x7
        temp.innerHTML = '<br><style>'+ cssRules +'</style>';
        wrap.appendChild( temp.children[1] );
    };
})(document);

Demo: codepen, jsfiddle


this link may helpful to you: 

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


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width