ChatGPT解决这个技术问题 Extra ChatGPT

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

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?


J
Jack G

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

FYI, document.head is supported in all major browsers.
@RobW - It's not supported in IE8 and below. It's supported in Modern browsers, but not all major ones.
why not just use document.querySelector("head")? It's event supported by IE8 by source
@allenhwkim: the answer predates introduction of querySelector(); today, I'd probably go with document.head, available since IE9
I had to append the style element to the head before accessing style.styleSheet.cssText. Before it was appended style.styleSheet was null.
S
Simone

<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", ``)

jQuery:

$('`

I'm red!

I'm blue!

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


Hi and welcome to the site. While this code may solve the given problem, you should also include an explanation of how and why it works.
S
Spooky

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 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.
True. I know and I knew that. But, sometimes, I am just too lazy to write as I am supposed to. :D Cheers.
i
iandotkelly

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

7
7vujy0f0hy

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.


T
Tony

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


J
Joel Ellis

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

Lorem Ipsum

dolar sit amet

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

Lorem Ipsum

dolar sit amet


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.
d
defend orca

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


m
moefinley

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


Injecting the style block dynamically into the head didn't update the styling in some cases. This works though!
S
Shujath

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.


There is no reason to use document.getElementsByTagName("head")[0]. document.head is supported by all major and modern browsers, all the way back to IE9.
Agreed. updated the answer as per your suggestion.
C
Chester Fung

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

V
Vinod Poorma
this link may helpful to you: 

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


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.