MaterializeCSS is one of the popular Material Design frameworks out there that does a good job in getting things right. Led by a team of 4 students and many more contributors around the world, it has grown so huge, with over 20k stars on Github, and for good reasons.

Article difficulty somewhere Intermediate Level

One of my favorite front-end frameworks is Foundation for Sites. What I always enjoyed about Foundation for Sites was the ability to quickly check some boxes and download customized version of their CSS with or without certain packages.

Unfortunately, since I started using MaterializeCSS, I have been looking for a similar, in-browser CSS Customizer for Materialize. I couldn’t, and so, I spent one weekend building it for personal use, as well as sharing with anyone online who might be interested.

Why you’re Here?

This article isn’t about telling you how good and cool the Custom Download Materialize site is, or how clean-looking and gentle it stands to be.

So, we’ll be using basically these tools:

NodeJS

ExpressJS

Node-Sass

MaterializeCSS (of course)

In this article, I share how to customize your CSS and download from the browser. I will share code snippets enough to guide you in building, hopefully, something similar to Custom Download Materialize.

Express Part

Express JS was the workable go-to solution that came to my mind when I planned on doing the project last week.

Did AngularJS cross my mind? Yep. I came across medialize/sass.js which allow you to compile Sass snippets into CSS right within the browser. The approach looked awesome. The challenges?

Network overhead was one. Bringing the ability to compile Sass to one’s browser can be heavy, and even if 500 kb per each visit, that is huge, both for the end user, and my server that’ll be serving these requests.

By the way, if you don’t have Devdocs, fully enabled in your browsers, then what kind of Web Developer are you? A Yoda’veloper?

In the long run, I felt such an approach will overwhelm my meager server specs and reduce scalability. For local use, that might not be an issue, but since I planned to deploy the solution onto my server for anyone interested in using.

The next issue I encountered after playing with the Sass.js was the lack thereof integration with AngularjS (or my knowing of how to). I opened a ticket about that, and the response I received felt more of a prank.

And so, instead of having to re-invent many things, probably, trying to use the Sass.js in my browser without AngularJS, I rethought about the whole process, and realize, it’ll be best letting the server handle the building process, besides, that is how I guess Foundation Zurb does theirs (??).

What about Express?

I won’t be teaching you ExpressJS in this article. You have the entire internet minus this blog to learn about Express, for example: devdocs.io/express.

Materialize.toast("Duh! Download Everything, or at least check a box!",7000);

returnfalse;

}

})

});

</script>

</html>

Take your time to read through the above snippet. Here’s what is happening, in union with our process steps listed above.

We have a form with many input checkboxes (only showing one above) with a name, and id attributes specified.

Take note of their names as they match what is found In the MaterializeCSS materialize.scss file. So grid is same as @import "components/grid"; in the .scss file.

Down in the script tag area, we see two scripts, one for ensuring that at least a single box is checked before the form can be submitted, and the other toggles all the checkboxes on the page.

You might be wondering why the choice of naming for the checkboxes are in the way they are at the moment. A view at the number 2) of our processes will shed some light on that.

[wp_ad_camp_1]

2) Server Receives form Post

First of all, if the ‘Download Everything’ box is checked, we want to build everything MaterializeCSS, at least that is what the user requests.

With that in mind, something like this comes first within the app.post(...) of Express. Bringing in our snippets from app.js, here we go:

1

2

3

4

5

6

7

8

9

app.post('/',function(req,res){

if(req.body.all==='on'){

console.log('Building for everything MaterializeCSS');

buildSass('./public/vendor/materialize/sass/materialize.scss',res);

returntrue;

}

// some more code here coming later

});

A few notes. Our form action was directed to the same homepage. Therefore, the app.post('/', function(...) { .. }); targets the same homepage

Our submitted form data is attached to the req.body object. In there, we have access to each of the keys in the object, just like any other usual Javascript object.

And so, we go ahead to see, if the request body has a all key (as in a form checkbox called all) comes in, with a value of on, as in, that checkbox is checked, then we run a buildSass() function. More on that buildSass() function later.

We return true; so that the code ends within the if block and does not proceed to hunt the other subsequent code. Within the buildSass(), a response is given, although.

buildSass();

Absorb the snippet below and let us discuss afterwards.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

functionbuildSass(destination,res){

sass.render({

file:destination,

includePaths:['./public/vendor/materialize/sass/components/'],

outputStyle:'compressed'

},function(error,result){// node-style callback from v3.0.0 onwards

if(error){

console.log(error.status);// used to be "code" in v2x and below

console.log(error.column);

console.log(error.message);

console.log(error.line);

res.render('index',{title:'Bad Error Express',result:'Error only'});

}else{

console.log(result.stats);

res.set({

'Content-Type':'text/css',

'Content-disposition':'attachment; filename=custom-download.css'

});

houseCleaning(destination);

returnres.send(result.css);

}

});

}

buildSass() takes two arguments: one is the location of the MaterializeCSS file to use for building the custom CSS, and the other argument is the response object. We include the response object so that we can send the user a response directly from the buildSass() wherever we call it.

The buildSass() is nothing special. All it does it use the sass.render synchronous function from node-sass

Nothing else happening there. Check the node-sass documentation for more details on how to use it. Upon error, we choose where to send the user to, or otherwise.

The file and includePaths are important. The file refers to the source materialize file to use in building, and the includePaths refers to what other places the rendering process can/should look for imported files.