JSFiddle - React, Tailwind, and code Playground
HTML
<p>Testing</p>
<div>Testing 2</div>
CSS
body {
background-color: red;
}
JavaScript
/*
https://jsfiddle.net/khrvndua/
Usage: adjustCSSRules('#myDiv', {width: '300px'}, 'style.css');
selector [string] - CSS selector. Whitespaces are auto-reduced.
'.myClass #myDiv' === '.myClass #myDiv'
rules [CSS string, object, JSON] - either of these.
{ border: "solid 3px green", color: "white" }
'border: solid 3px green; color: white'
sheet Optional [string, StyleSheet]
Optional - defaults to checking all stylesheets and appending to last one when needed.
'myStyles.css'
'https://example.com/style.css'
document.styleSheets[1]
*/
function adjustCSSRules(selector, props, sheets){
// get stylesheet(s)
if (!sheets) sheets = [...document.styleSheets];
else if (sheets.sup){ // sheets is a string
let absoluteURL = new URL(sheet, document.baseURI).href;
sheets = [...document.styleSheets].filter(i => i.href == absoluteURL);
}
else sheets = [sheets]; // sheets is a stylesheet
// CSS (& HTML) reduce spaces to one. TODO: ignore quoted spaces.
selector = selector.replace(/\s+/g, ' ');
const findRule = s => [...s.cssRules].reverse().find(i => i.selectorText == selector)
let rule = sheets.map(findRule).filter(i=>i).pop()
const propsArr = props.sup
? props.split(/\s*;\s*/).map(i => i.split(/\s*:\s*/)) // from string
: Object.entries(props); // from Object
if (rule) for (let [prop, val] of propsArr)
rule.style[prop] = val;
else {
sheet = sheets.pop();
if (!props.sup) props = propsArr.reduce((str, [k, v]) => `${str}; ${k}: ${v}`, '');
sheet.insertRule(`${selector} { ${props} }`, sheet.cssRules.length);
}
}
var s = document.styleSheets[1];
adjustCSSRules("body", 'background-color: green');
adjustCSSRules("body", {"background-color": "purple"});
adjustCSSRules("p", {border: '2px solid blue'}, s);
adjustCSSRules("div", {color: 'yellow'},...