Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject CSS stylesheet as string using Javascript

I'm developing a Chrome extension, and I'd like users to be able to add their own CSS styles to change the appearance of the extension's pages (not web pages). I've looked into using document.stylesheets, but it seems like it wants the rules to be split up, and won't let you inject a complete stylesheet. Is there a solution that would let me use a string to create a new stylesheet on a page?

I'm currently not using jQuery or similar, so pure Javascript solutions would be preferable.

like image 877
Dan Hlavenka Avatar asked Mar 19 '13 16:03

Dan Hlavenka


People also ask

How do you inject CSS styles?

There are three ways to add CSS to HTML. You can add inline CSS in a style attribute to style a single HTML element on the page. You can embed an internal stylesheet by adding CSS to the head section of your HTML doc. Or you can link to an external stylesheet that will contain all your CSS separate from your HTML.

Can you manipulate CSS with JavaScript?

Now, JavaScript is a powerful language, so not only can we manipulate HTML elements with it, but we can also use it to manipulate the CSS properties of any webpage.

How do you inject CSS in HTML?

CSS can be added to HTML documents in 3 ways: Inline - by using the style attribute inside HTML elements. Internal - by using a <style> element in the <head> section. External - by using a <link> element to link to an external CSS file.


2 Answers

There are a couple of ways this could be done, but the simplest approach is to create a <style> element, set its textContent property, and append to the page’s <head>.

/**  * Utility function to add CSS in multiple passes.  * @param {string} styleString  */ function addStyle(styleString) {   const style = document.createElement('style');   style.textContent = styleString;   document.head.append(style); }  addStyle(`   body {     color: red;   } `);  addStyle(`   body {     background: silver;   } `); 

If you want, you could change this slightly so the CSS is replaced when addStyle() is called instead of appending it.

/**  * Utility function to add replaceable CSS.  * @param {string} styleString  */ const addStyle = (() => {   const style = document.createElement('style');   document.head.append(style);   return (styleString) => style.textContent = styleString; })();  addStyle(`   body {     color: red;   } `);  addStyle(`   body {     background: silver;   } `); 

IE edit: Be aware that IE9 and below only allows up to 32 stylesheets, so watch out when using the first snippet. The number was increased to 4095 in IE10.

2020 edit: This question is very old but I still get occasional notifications about it so I’ve updated the code to be slightly more modern and replaced .innerHTML with .textContent. This particular instance is safe, but avoiding innerHTML where possible is a good practice since it can be an XSS attack vector.

like image 107
Liam Newmarch Avatar answered Sep 20 '22 17:09

Liam Newmarch


Thanks to this guy, I was able to find the correct answer. Here's how it's done:

function addCss(rule) {   let css = document.createElement('style');   css.type = 'text/css';   if (css.styleSheet) css.styleSheet.cssText = rule; // Support for IE   else css.appendChild(document.createTextNode(rule)); // Support for the rest   document.getElementsByTagName("head")[0].appendChild(css); }  // CSS rules let rule  = '.red {background-color: red}';     rule += '.blue {background-color: blue}';  // Load the rules and execute after the DOM loads window.onload = function() {addCss(rule)}; 

fiddle

like image 42
John R Perry Avatar answered Sep 22 '22 17:09

John R Perry