How to use CSSStyleSheet.insertRule() properly?
It is slightly confusing but your code does actually work, it is just that you can't see the inserted rules in the XML tree returned.
To verify that your code works, there are two tests you can do:
var style = (function() { // Create the <style> tag var style = document.createElement("style");
// WebKit hack style.appendChild(document.createTextNode(""));
// Add the <style> element to the page document.head.appendChild(style); console.log(style.sheet.cssRules); // length is 0, and no rules
return style;})();style.sheet.insertRule('.foo{color:red;}', 0);console.log(style.sheet.cssRules); // length is 1, rule added
<p class="foo"> I am some text</p>
How to use CSSStyleSheet.insertRule() in Internet Explorer properly?
In IE11 the error is fixed if I add the index parameter:
var style = document.createElement('style');
document.head.appendChild(style);
style.sheet.insertRule('td {overflow: visible}', 0);
related: How to use CSSStyleSheet.insertRule() properly?
JavaScript stylesheet.insertRule not inserting rule but returns no errors or exceptions
The code does work. Note that, when using CSSStyleSheet.insertRule()
, the rules are actually inserted into the style sheet although they do not show up in the XML tree. Also see: https://stackoverflow.com/a/28930990/2692307
Below an working example, I've just added a sample dataset and changed the css rules to better prove the example.
let addCSSRule = function(sheet, selector, rules, index) { sheet.insertRule(selector + "{" + rules + "}", index); };
let styleTagGenerator = function() { let tag = document.createElement('style'); tag.id = 'myskills_dynamic_style'; tag.type = 'text/css'; document.head.appendChild(tag);};
let response = { // Example object test: 'bada55'};
for(let key in response) { let val = response[key]; let selector = '.progressbar-bg span.progressbar-' + key + ''; // Removed :after to visualize it better let rule = 'background-color: #' + val + ''; // Use bg-color instead of animation to visualize it better let styleTag = document.getElementById('myskills_dynamic_style').sheet; addCSSRule(styleTag, selector, rule, response.length);}
<style id="myskills_dynamic_style"></style>
<div class="progressbar-bg"> <span class="progressbar-test">abc</span></div>
Update or remove css rule from insertRule() in JS
To delete just use deleteRule() passing in the index that the rule was inserted at
var index = document.styleSheets[0].insertRule(`#li${i}:after {content: "${data[2][i]}"; }`, 0);
document.styleSheets[0].deleteRule(index);
In order to update a rule access the cssRules
list at the index the rule was inserted at, and change the style property
document.styleSheets[0].cssRules[index].style.content = "";
Note you will not be able to access the rule if the style sheet being accessed was linked externally as cssRules
will be null. So you will have to delete it and insert it back to change its styles.
Demo
var stylesheet = document.styleSheets[0];var ruleIndex = 0;
function redRule(){ stylesheet.cssRules[ruleIndex].style.color = "red";}
function blueRule(){ stylesheet.cssRules[ruleIndex].style.color = "blue";}
function replaceRule(){ stylesheet.deleteRule(ruleIndex); ruleIndex = stylesheet.insertRule("body { color:yellow; }",0); }
ruleIndex = stylesheet.insertRule("body { color:black; }",0);
document.addEventListener('click',function(e){ switch(e.target.id){ case 'red': redRule(); break; case 'blue': blueRule(); break; case 'replace': replaceRule(); break; }});
<style></style>Text<br><button id="red">Change rule to red</button><br><button id="blue">Change rule to blue</button><br><button id="replace">Replace rule</button><br>
handling cssRules with javascript properly
add an empty style tag to your page with some id like --
<style id="customstyles" type="text/css"></style>
and then under resize event handler-
var sheets = document.styleSheets;
for (var i = 0; i < sheets.length; i++) {
var sheet = sheets[i];
if (sheet.ownerNode.id == "customstyles") {
var rules = sheet.cssRules;
if (rules.length > 0) {
// instead of addRule, modify the existing rule with following code-
var style = "css attribute on which you are applying new value";
var stylevalue = "the value to be applied";
for (var j = 0; j < rules.length; j++) {
var rule = rules[j];
if (rule.selectorText == selector) {
rule.style.setProperty(style, stylevalue);
break;
}
}
}
else {
// call you code to insert new cssRule
stylesheet.insertRule(selector + ' { ' + rule + ' }', stylesheet.cssRules.length);
}
break;
}
}
Hope that helps
Create a CSSStyleSheet object from a CSS string?
Here's a function that does this:
function CSSString2CSSStyleSheet ( css ) {
const style = document.createElement ( 'style' );
style.innerText = css;
document.head.appendChild ( style );
const {sheet} = style;
document.head.removeChild ( style );
return sheet;
}
Related Topics
The Purpose of Starting an Initial Comment with /*! in JavaScript and CSS Files
Resize Cross Domain Iframe Height
Remove/Reset Inherited CSS from an Element
Disabling the Context Menu on Long Taps on Android
A Component Is Changing an Uncontrolled Input of Type Text to Be Controlled Error in Reactjs
Does Every JavaScript Function Have to Return a Value
What Exactly Is the Parameter E (Event) and Why Pass It to JavaScript Functions
Image.Onload Event and Browser Cache
How to Access the Request Body When Posting Using Node.Js and Express
Find Dom Element by Id When Id Contains Square Brackets
How to Tell When a CSS Background Image Has Loaded? Is an Event Fired
Detecting by How Much User Has Scrolled
How to Show Just the First Line of Text of a Div and Expand on Click
JavaScript Alert Not Working in Android Webview
How to Check If an Element Exists in the Visible Dom
When a 'Blur' Event Occurs, How to Find Out Which Element Focus Went *To*