Load variables into LESS CSS preprocessor from JSON file

Billy Moon picture Billy Moon · Oct 8, 2013 · Viewed 7.1k times · Source

Is it possible to load variables into LESS CSS preprocessor from a JSON file like you can do with Stylus?

With contents of file myvars.json

{
    "color1": "#112345",
    "color2": "#667890"
}

In Stylus I do...

json('myvars.json')
body{ background-color: color1; }

Is it possible to do this in LESS?

I want to keep the file as JSON, so I can easily re-use it in javascript.

Answer

Martin Turjak picture Martin Turjak · Oct 9, 2013

In less.js you can make use of javascript interpolation (using the back-ticks). And call a function that loads the json object with the variables from the file ... from which you can extract the variable by its key - something in this direction perhaps:

@json_file: myvars.json;

@json: ~`json = function($key) { var request = new XMLHttpRequest(); request.open("GET", "@{json_file}", false); request.send(null); var my_json = JSON.parse(request.responseText); return my_json[$key]; }`;

body {
  background-color: ~`json('color1')`;
}

this might not look super elegant, but it works. A more elegant option would probably be to define your custom user function in the global LESS object before calling the script, but I never really bothered playing with that, as I was always using LESS client-side just in development.

Another thing that you can do - is loading the json file in javascript (after calling the LESS script in the browser) and using the less.modifyVars() function to recompile LESS with the json variables. You can do something along this lines in your html (here I use plain JS but it's even simpler if you use jQuery.getJSON):

<link rel="stylesheet/less" href="style.less" type="text/css">
<script type="text/javascript">less = { env: "development" };</script>
<script src="http://rawgithub.com/less/less.js/master/dist/less-1.4.1.min.js" ></script>
<script type="text/javascript">
    var request = new XMLHttpRequest();
    request.open("GET", "myvars.json", false);
    request.send(null);
    var my_json = JSON.parse(request.responseText);
    less.modifyVars(my_json);
</script>

and something like this in your LESS style file:

@color1: darkblue; //default value - will get overwritten by .modifyVars()

body {
  background-color: @color1;
}

Another note: all variable names in LESS have to begin with an at sign (@). However, the json variables do not need to, because less.modifyVars() automatically prepends the variables with an @ if missing.

Hope this gives you some ideas. There might be better ways to do it ... but this two approaches worked for me.