Reputation: 3937
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?
Upvotes: 3
Views: 874
Reputation: 3937
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! :)
Upvotes: 1
Reputation: 3749
Here is what i have tried so far,
This is My folder Structure. My SCSS
Files get Compiled to CSS
using gulp
SCSS File
body{
background-color: black;
}
CSS File
body{
background-color: black;
}
script.js
(function(){
var style = document.createElement("style");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(){
if(this.readyState == 4 && this.status == 200){
style.innerHTML = this.responseText;
}
};
xhttp.open("GET","../css/style.css",true);
xhttp.send();
document.head.appendChild(style);
})();
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="js/script.js"></script>
</body>
</html>
Here is what i have done. I have created a IIFE(immediately-invoked function expression) which creates a style
element. I am making a ajax request to my style.css
file and fetching its contents. and finally appending it to head
section. I haven't included the link
tag. I am loading the styles from JS.
Is this what you expected?
Upvotes: 0