Page-Level CSS Variables
Since IE & Edge don't currently support CSS variables, this is another approach. Particularly useful for things like white-labeling a SPA without having to build CSS files or tightly couple CSS to JS/HTML templates.
by nathanlogan
HTML
<div>
<p>This is styled with dynamically-applied CSS?!</p>
</div>
<p>This too?!</p>
<p class="getDefault">But not this. :( </p>
CSS
/* default CSS could be delivered to the page here... */
p {
padding: 20px;
background-color: orange;
}
JavaScript
////////////////////////////////////////////////////////////
// Variables to modify
////////////////////////////////////////////////////////////
// the CSS templates, with CSS variable syntax (this could also be created by parsing a CSS file)
let toStyle = [
{
selector: 'div',
rules: 'padding: var(--standardPadding); background-color: var(--primaryBackgroundColor); border: 2px solid var(--secondaryBackgroundColor)'
},
{
selector: 'p:not(.getDefault)',
rules: 'padding: var(--standardPadding); background-color: var(--secondaryBackgroundColor); color: #fff;'
}
]
// the variable names and values for replacement
const variables = {
'primaryBackgroundColor': '#ccc',
'secondaryBackgroundColor': 'navy',
'standardPadding': '20px'
}
////////////////////////////////////////////////////////////
// Utility functions
////////////////////////////////////////////////////////////
// This function will create a new dynamic stylesheet.
// (from https://davidwalsh.name/add-rules-stylesheets)
const createNewSheet = function () {
var style = document.createElement('style')
// WebKit hack :(
style.appendChild(document.createTextNode(''))
// Add the <style> element to the page
document.head.appendChild(style)
return style.sheet
}
// This function is a cross-browser way to add style rules to a stylesheet.
// (from https://davidwalsh.name/add-rules-stylesheets)
function addCSSRule (sheet, selector, rules, index = 0) {
// W3C-supported way...or IE way
if ('insertRule' in sheet) {
sheet.insertRule(selector + '{' + rules + '}', index)
} else if ('addRule' in sheet) {
sheet.addRule(selector, rules, index)
}
}
////////////////////////////////////////////////////////////
// Logic to do the replacement and get it on the page
////////////////////////////////////////////////////////////
// create our dynamic stylesheet
let newSheet = createNewSheet()
// run through our elements to style
for (let i = 0, len = toStyle.length; i <...