Add CSS to <head> with JavaScript?

JavascriptHtmlCss

Javascript Problem Overview


Is there a way to add css from a string in the javascript file to the head of a document with javascript?

Let's say we have a webpage, which has a lightbox script, this script requires a css file to function.

Now adding this css file with <link> will make the css file download even for people that don't have js enabled.

I know that I can dynamically load the css file with the script, but that also means that there will be 2 http requests, and in cases where there is little to no css in the file I find this inefficient.

So I thought to myself, what if you could put the css that you have in the css file, into the script, have the script parse the css and add it into the head, or even better just have the script add the css directly into the <head> of the document.

But I have found nothing online that suggests that this is possible, so is it possible to add css to the head with js?

Edit + SOLUTION:

I edited roryf's answer to work cross browser (except IE5)

Javascript:

 function addcss(css){
	var head = document.getElementsByTagName('head')[0];
	var s = document.createElement('style');
	s.setAttribute('type', 'text/css');
	if (s.styleSheet) {   // IE
		s.styleSheet.cssText = css;
	} else {                // the world
		s.appendChild(document.createTextNode(css));
	}
	head.appendChild(s);
 }

Javascript Solutions


Solution 1 - Javascript

Edit: As Atspulgs comment suggest, you can achieve the same without jQuery using the querySelector:

document.head.innerHTML += '<link rel="stylesheet" href="styles.css" type="text/css"/>';

Older answer below.


You could use the jQuery library to select your head element and append HTML to it, in a manner like:

$('head').append('<link rel="stylesheet" href="style2.css" type="text/css" />');

You can find a complete tutorial for this problem here

Solution 2 - Javascript

As you are trying to add a string of CSS to <head> with JavaScript? 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.

var linkElement = 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

The solution you have marked will work but this solution requires fewer dom operations and only a single element.

Solution 3 - Javascript

If you don't want to rely on a javascript library, you can use document.write() to spit out the required css, wrapped in style tags, straight into the document head:

<head>
  <script type="text/javascript">
    document.write("<style>body { background-color:#000 }</style>");
  </script>
  # other stuff..
</head>

This way you avoid firing an extra HTTP request.

There are other solutions that have been suggested / added / removed, but I don't see any point in overcomplicating something that already works fine cross-browser. Good luck!

http://jsbin.com/oqede3/edit

Solution 4 - Javascript

A simple non-jQuery solution, albeit with a bit of a hack for IE:

var css = ".lightbox { width: 400px; height: 400px; border: 1px solid #333}";

var htmlDiv = document.createElement('div');
htmlDiv.innerHTML = '<p>foo</p><style>' + css + '</style>';
document.getElementsByTagName('head')[0].appendChild(htmlDiv.childNodes[1]);

It seems IE does not allow setting innerText, innerHTML or using appendChild on style elements. Here is a bug report which demonstrates this, although I think it identifies the problem incorrectly. The workaround above is from the comments on the bug report and has been tested in IE6 and IE9.

Whether you use this, document.write or a more complex solution will really depend on your situation.

Solution 5 - Javascript

Here's a function that will dynamically create a CSS rule in all major browsers. createCssRule takes a selector (e.g. "p.purpleText"), a rule (e.g. "color: purple;") and optionally a Document (the current document is used by default):

var addRule;

if (typeof document.styleSheets != "undefined" && document.styleSheets) {
    addRule = function(selector, rule) {
        var styleSheets = document.styleSheets, styleSheet;
        if (styleSheets && styleSheets.length) {
            styleSheet = styleSheets[styleSheets.length - 1];
            if (styleSheet.addRule) {
                styleSheet.addRule(selector, rule)
            } else if (typeof styleSheet.cssText == "string") {
                styleSheet.cssText = selector + " {" + rule + "}";
            } else if (styleSheet.insertRule && styleSheet.cssRules) {
                styleSheet.insertRule(selector + " {" + rule + "}", styleSheet.cssRules.length);
            }
        }
    }
} else {
    addRule = function(selector, rule, el, doc) {
        el.appendChild(doc.createTextNode(selector + " {" + rule + "}"));
    };
}

function createCssRule(selector, rule, doc) {
    doc = doc || document;
    var head = doc.getElementsByTagName("head")[0];
    if (head && addRule) {
        var styleEl = doc.createElement("style");
        styleEl.type = "text/css";
        styleEl.media = "screen";
        head.appendChild(styleEl);
        addRule(selector, rule, styleEl, doc);
        styleEl = null;
    }
};

createCssRule("body", "background-color: purple;");

Solution 6 - Javascript

Here's a simple way.

/**
 * Add css to the document
 * @param {string} css
 */
function addCssToDocument(css){
  var style = document.createElement('style')
  style.innerText = css
  document.head.appendChild(style)
}

Solution 7 - Javascript

In one call:

document.head.appendChild(Object.assign(document.createElement("style"), {textContent: `
    select, button, input, details, summary { cursor: pointer }
    input { padding: 0.5rem }
    button, select  { margin: 0.5rem }
    @media (max-width:640px) { button  { width: 100% } i {display: block } }
  `
}))

Solution 8 - Javascript

Shortest One liner:

const addCSS = css => document.head.appendChild(document.createElement("style")).innerHTML = css;

// Usage:
addCSS("body{background:red}");

Solution 9 - Javascript

Late to the party, quite similar to all solution but appends only once the script to the head:

export const injectHeadCss = () => {
  let style: HTMLStyleElement | null = document.head.querySelector('style[my-style]');

  if (style !== null) {
    return;
  }

  style = document.createElement('style');
  style.setAttribute('my-style', '');
  style.innerHTML = `
    .class1 {
      background: pink;
    }

    .class2 {
      background: purple;
    }
  `;

  document.head.append(style);
};

Solution 10 - Javascript

Maximizing compatibility, working for most things made 2009-2022 and likely beyond. This solution is intentionally not made with ES6 etc; using an arrow function, let-variable, append (2014) etc.

This short version adds styling to the head-section of a web page and can also be done via the DOM to access the head-section to maximize compatibility further - since querySelector wasn't widely adapted until 2009.

Note that innerHTML / write nowadays isn't recommended for production.

Just copy+paste it into the console to try it out and a page like this gets some nice additions;

function ahsf(styling){ document.querySelector('head').innerHTML+="<style>"+ styling +"</style>";}
//Called with
ahsf(" * { border: 1px dashed #f09 !important; } ");

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTimo HuovinenView Question on Stackoverflow
Solution 1 - JavascriptthomauxView Answer on Stackoverflow
Solution 2 - JavascriptmoefinleyView Answer on Stackoverflow
Solution 3 - JavascriptJerikoView Answer on Stackoverflow
Solution 4 - JavascriptroryfView Answer on Stackoverflow
Solution 5 - JavascriptTim DownView Answer on Stackoverflow
Solution 6 - JavascriptAllyView Answer on Stackoverflow
Solution 7 - JavascriptNVRMView Answer on Stackoverflow
Solution 8 - JavascriptchickensView Answer on Stackoverflow
Solution 9 - JavascriptDavid Dal BuscoView Answer on Stackoverflow
Solution 10 - JavascriptK. Kilian LindbergView Answer on Stackoverflow