I'm having trouble articulating what I want, but I'm sure this has been asked before. I'm looking for a way to use gulp to inject precompiled CSS into a javascript function that executions at runtime. Basically, something like this:
build/index.html
Contents:
<div> <!-- content here --></div>
build/index.css
Contents:
div {
background:red;
}
/* more rules */
Compiles to something like this:
dist/index.html
Contents:
<script>(function(){
var style=document.createElement('style');
style.innerHTML='div{background:red;} /* all the other rules */';
document.head.appendChild(style);
}());</script>
<div></div>
It doesn't have to resemble this exactly, but I hope my meaning is clear. I'm looking for away to avoid the work of converting my css into an inline string capable of being injected into the head at runtime by js.
Is this clear? Do you know of anything that assists in this process?
For anyone else having a similar problem, this is how I solved the problem.
Starting with the gulp-css-to-js-style plugin by spacerockzero, I made some minor modifications to his code and achieve exactly what I wanted. As it stood in the beginning, the plugin was a single file with no dependencies. You can see his original code on Github. This is what I came up with:
'use strict';
var through = require('through2');
/**
* Inject style tag with my minified, one-line css
*/
module.exports = function injectCSS() {
var stream = through.obj(function(file, enc, cb) {
var template = 'function injectStyles(rule) {\n' +
'var style = document.createElement("style");\n' +
'style.innerHTML = rule;\n' +
'document.head.appendChild(style);\n' +
'}\n' +
"injectStyles('" + file.contents + "');\n";
file.contents = new Buffer(template);
this.push(file);
cb();
});
return stream;
}
The only caveat was that I found that I was unable to include CSS Media Queries
and @keyframes
anywhere but at the beginning of the CSS files - (I'm sure there is a fix for this, I just didn't dig into it). So, I just created multiple css files, and the script executed multiple times and thus created multiple style elements. Here is an example of what got appended to my HTML on page load.
<script>
(function(){
function injectStyles(rule) {
var style = document.createElement("style");
style.innerHTML = rule;
document.head.appendChild(style);
}
injectStyles('@media(min-width:375px){.visible-content{margin-left:auto !important}}');
}());
</script>
Hope this is useful to someone else! :)