Reputation: 19275
I have the content of a CSS file as a string I got with an AJAX request.
I need to break it into rules that I can feed into styleSheet.insertRule
What is the best way to achieve this correctly and efficiently ? I do not want to include/write a full CSS parser just for that if possible ...
I considered simply splitting on '}' but this will not work if there are @media clauses which created nested curly brackets, and I am not sure it is correct otherwise ...
Thanks!
Upvotes: 0
Views: 135
Reputation: 62743
The solution from Nisarg Shah probably does the job, but here's an alternative. It uses the css.js
library to parse the CSS string into a JS array, which can then be inserted using stylesheet.insertRule()
.
The two advantages this method has:
Also, this is a simplified solution that will not work with more complicated CSS containing media queries or similar rules. For a more robust solution, the function would need to handle those types of style rules, and more info on how to do that can be found in the MDN docs.
Here's the approach:
insertRule()
var cssString = `
div {
color: green;
font-size: 24px;
}`;
setTimeout(function() {
var parsedStyles = addStylesAndReturnParsedStyles(cssString);
console.log(parsedStyles)
}, 1000);
var addStylesAndReturnParsedStyles = function(cssString) {
var parser = new cssjs();
var parsed = parser.parseCSS(cssString);
var styleEl = document.createElement('style'),
styleSheet;
// Append style element to head
document.head.appendChild(styleEl);
// Grab style sheet
styleSheet = styleEl.sheet;
parsed.forEach(style => {
var selector = style.selector;
var rules = style.rules;
var propStr = '';
for (var i = 0; i < rules.length; i++) {
var prop = rules[i];
propStr += prop.directive + ':' + prop.value + ';\n';
}
// Insert CSS Rules
styleSheet.insertRule(selector + '{' + propStr + '}', styleSheet.cssRules.length);
});
return parsed;
};
<script src="https://cdn.rawgit.com/jotform/css.js/master/css.min.js"></script>
<div>Here's some content</div>
Upvotes: 1
Reputation: 14531
You can simply create a new <style>
element using the stylesheet text you have and insert it into the <head>
element.
var style = `
div {
color: blue;
}`;
setTimeout(function() {
var elem = document.createElement("style");
elem.innerHTML = style;
document.head.appendChild(elem);
}, 1000);
<div>
Some text
</div>
Upvotes: 1