Rewriting CSS using Javascript
I've been working on an HTML5 webapp project and the directory structure is set up like this:
/app
webapp.html
/img
/js
/css
/design
test.html
The app has a build process that lints, compresses, and inlines the Javascript and CSS (compiled
scss files) into webapp.html, which means that all of the background-image:url()
attributes need to
use URLs that are relative to the app directory. I can't use full URLs because the domain can be
either dev.domain.com, test.domain.com, or www.domain.com depending on the which server it's
deployed to.
To speed up development I create static HTML files in the /design
directory that link to the CSS
and Javascript files in the /app
directory. This makes it much faster to code and test since all it
takes is a page refresh on my local MAMP server to run the new code.
The design page includes the css file:
<link type="text/css" media="screen" rel="stylesheet" href="../app/css/appstyle.css">
…which include rules like this:
background-image: url(img/graphic.svg);
The problem being that the url is relative to the css file. Since the css is inlined in the
webapp, the relative link to the img directory works fine. When using the source CSS file it's
looking for /app/css/img/graphic.svg
My solution was to write some Javascript for the test files that located and rewrote the
offending rules. Changing url(img/
to url(../img/
did the trick.
$(document).ready(function () {
var sheets = document.styleSheets;
const regexSheet = /appstyle.css/; // Locate the stylesheet to modify
const regexUrl = /url\("img\//; // Match relative url links
for (let i = 0; i < sheets.length; i++) {
if (regexSheet.test(sheets[i].href)) {
// We've got our target stylesheet, now loop through the rules
for (let j = 0; j < sheets[i].rules.length; j++) {
if (typeof sheets[i].rules[j].style !== 'undefined') {
// This rule has styles
let rule = sheets[i].rules[j].style;
if (typeof rule.backgroundImage !== 'undefined'
&& regexUrl.test(rule.backgroundImage)) {
let newUrl = rule.backgroundImage.replace(/"img\//, '"../img/');
sheets[i].rules[j].style.backgroundImage = newUrl;
}
}
}
}
}
Other than some error messages in console for the images that were not found before the code executed, it works perfectly and I can add image links at will now.