How to create a <style> tag with Javascript?
JavascriptHtmlCssJavascript Problem Overview
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
-
Is nicer
-
Works with Chrome?
Or maybe
-
This is a non-standard thing I should avoid
-
Three working browsers are great and who uses Chrome anyway?
Javascript Solutions
Solution 1 - Javascript
Try adding the style
element to the head
rather than the body
.
This was tested in IE (7-9), Firefox, Opera and Chrome:
var css = 'h1 { background: red; }',
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
head.appendChild(style);
style.type = 'text/css';
if (style.styleSheet){
// This is required for IE8 and below.
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
Solution 2 - Javascript
<style>
tags should be placed 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:
document.head.insertAdjacentHTML("beforeend", `<style>body{background:red}</style>`)
jQuery:
$('<style>').text("body{background:red}").appendTo(document.head)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Solution 3 - Javascript
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
Solution 4 - Javascript
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;');
Solution 5 - Javascript
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);
Solution 6 - Javascript
const style = document.createElement("style")
style.textContent = "h1 { background-color: red; }"
document.head.appendChild(style)
The Modern & Easy Way
The code above is the gist of it; continue reading if you want to know the reasoning.
Why another answer? The accepted answer is old and includes redundant code for outdated browsers like the Internet Explorer. Other answers are unnecessarily complex or use properties like .innerHTML
that allow for cross-site scripting attacks.
type
property is not needed
The Most of the anwsers set the type
property like so: style.type = "text/css"
. Setting this property is not necessary unless you need to support older browsers.
According to <style>: The Style Information element - HTML | MDN, the type
attribute is optional and defaults to text/css
:
> type
>
> This attribute defines the styling language as a MIME type (charset should not be specified). This attribute is optional and defaults to text/css
if it is not specified; values other than the empty string or text/css
are not used. Note: There is very little reason to include this attribute in modern web documents.
Adding the CSS
To add the CSS, use .textContent
as it is safer and faster than alternative methods. Opposite to .innerHTML
, it does not parse HTML and can therefore prevent cross-site scripting attacks.
Another similar property, .innerText
, is like .textContent
but takes CSS styles into account and represents only the "rendered" text content. As we are not interested in "rendered"-only content we prefer .textContent
.
.textContent
do?
What does setting Setting the .textContent
property removes all the node's (element's) children and replaces them with the given string value.
Where to place the element?
The style element should be included in the head: "The <style>
element must be included inside the <head>
of the document. ...". [<style> ... | MDN]
To get the head use document.head
as it has been supported by all major browsers for a long time already so there is no need for other fallbacks.
Solution 7 - Javascript
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][1], [jsfiddle][2] [1]: http://codepen.io/anon/pen/vtHCs [2]: http://jsfiddle.net/8h09zkht/
Solution 8 - Javascript
document.head.innerHTML += `
<style>
h1 {
color: red;
}
p {
color: blue;
}
</style>`
<h1>I'm red!</h1>
<p>I'm blue!</p>
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
Solution 9 - Javascript
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);
}
}
}
Solution 10 - Javascript
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();
Solution 11 - Javascript
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.
Solution 12 - Javascript
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
Solution 13 - Javascript
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>
Solution 14 - Javascript
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
Solution 15 - Javascript
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
Solution 16 - Javascript
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.
Solution 17 - Javascript
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;
}
Solution 18 - Javascript
this link may helpful to you: