Add CSS to <head> with JavaScript?

Viewed 130353

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

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

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

Shortest One liner:

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

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

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

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