I want to add a CSS rule to the DOM:
This is my code
function empty_rule(sheet, class_name) {
const index = sheet.cssRules.length;
sheet.insertRule(`.${class_name} { }`, index);
return sheet.cssRules[index];
}
function make_style() {
const $head = $('head');
const $style = $('<style type="text/css"/>').appendTo($head);
return $style.get(0).sheet;
}
function set_css(sheet, class_name, style) {
const selector = `.${class_name}`;
let rule = [...sheet.cssRules].find(rule => {
return rule.selectorText === selector;
});
if (!rule) {
rule = empty_rule(sheet, class_name);
}
Object.assign(rule.style, style);
}
const sheet = make_style();
const rule = empty_rule(sheet, 'cmd-terminal');
console.log(sheet);
console.log(rule);
/*
set_css(sheet, 'cmd-terminal', {
color: 'red'
});
*/
On CodePen I’ve added this CSS to see the CSS:
style {
display: block;
white-space: pre;
font-family: monospace;
}
But I don’t see any CSS added, I attempt to add the given CSS in the comments. But I don’t even see the empty rule. I was asking chatGPT but it gave no help in solving the issue.
Here is the CodePen link
I use the cash library (lightweight jQuery alternative).
I was trying to add display: block;
to the empty rule (it was a chatGPT suggestion) but it didn’t solve the issue.
I even tried what is in MDN:
$('body style').get(0).sheet.insertRule("#blanc { color: white }", 0);
but the style didn’t change.
EDIT: I’ve added:
This HTML:
<p id="blanc">hello</p>
I have the same behavior in Firefox, Google Chrome, and Safari.
and the tag disappears when JavaScript runs. So the question is why The style is not updated in DOM (devTools) and why The style I’ve added doesn’t appear (when added display: block
)?
Is it possible to update the DOM so you can debug the CSS more easily?
3
Answers
So it seems the cssRules are not visible in the DOM. But you can create debug code that will dump the CSS and add it back to the DOM:
This will render dynamic CSS into the DOM. This code can be used while debugging.
See this fork of the original CodePen demo.
It seems you are expecting that modifying "virtual"
sheet.CSSRules
will be reflected back into HTMLStyleElement’s "innerHTML
". But apparently, it will not:This demonstrates that adding a new rule into sheet attached to style element has effect without changing original element’s content.
In a web page, the Document Object Model (DOM) is not immediately updated to reflect changes made to a stylesheet by using the insertRule method to add new CSS rules. This can often confuse developers who assume that using insertRule to add a new CSS rule will change the page’s styling right away.
This is because the CSS Object Model (CSSOM) provides the insertRule method, which functions at a lower level than the DOM. It doesn’t cause the page to automatically reflow or repaint; instead, it lets you programmatically add new CSS rules to a stylesheet. Stated differently, it prevents the browser from instantly recalculating the styles and updating the rendered output.
Usually, you have to force a reflow or repaint of the page in order to observe the consequences of the newly inserted CSS rule. A DOM element’s class name can be changed, its inline style can be updated, or a layout change can be forced. Here’s an example of how to apply a recently added CSS rule to a particular JavaScript element:
In this example, we edit the inline style of a particular p element to instantly apply the new style and include a new CSS rule to change the text color of all p elements to red.
While insertRule enables dynamic stylesheet editing, it may only support a limited number of older browsers. As such, you should use caution while using it to prevent unexpected behavior. For updating the DOM and changing styles dynamically, classes and JavaScript are being used more frequently.