26

I'm looking at using less.js (looks great), but our site requires that some styles be loaded dynamically after initial page load. It seems, however, that all LESS stylesheets must be loaded prior to the less.js script load. i.e. this works

<link rel="stylesheet/less" href="/static/less/style.less"/>
<script src="http://lesscss.googlecode.com/files/less-1.0.30.min.js"></script>

but it fails if the lines are swapped around, neither firefox nor chrome appear to attempt loading 'style.less' unless they are ordered correctly. The ordering requirement is noted explicitly in this tutorial.

Is there any way to load less stylesheets after initial page load?

Note that this blog describes a 'watch' feature -

which will auto-refresh the CSS whenever you save your LESS code

so it seems reasonable to expect that I could add some LESS rules after page load. Feels like I'm missing something.

Cheers,

Colin

UPDATE: code used to test behaviour described in comments (less style sheet listed after the script) -

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Simple</title>

  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
  <script src="/static/js/less-1.0.31.min.js"></script> 
  <link rel="stylesheet/less" href="/static/less/style.less" id="abc123"/>
</head>
<body>
  <div id="container">
    <div>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.</div>
  </div>
  <div id="#abc">Bingo</div>
</body>

<script>
console.log("refreshing styles...");
less.sheets.push(document.getElementById('abc123'));
//var lessStyle = $("<style>#abc { color: blue; }</style>").attr("id", "less:static-less-style").attr("type", 'text/less');
//$("head").append(lessStyle);
less.refresh(true);
console.log("refreshed...");
</script>
</html>

and the less stylesheet

@primary_color: green;

.rounded(@radius: 5px) {  
  -moz-border-radius: @radius;  
  -webkit-border-radius: @radius;  
  border-radius: @radius;  
}

#container {
  background: @primary_color;
  .rounded(5px);

  div {
    color: red;
  }
}
hawkett
  • 3,053
  • 5
  • 29
  • 39
  • Sorry for the anti-answer, but can you elaborate on why you intend to add CSS rules after page load? – Steven Jul 04 '10 at 19:33
  • The site contains user contributed widgets, and users contribute css (or less, hopefully) themselves. A given page might display many widgets. It doesn't reload the entire page when a new widget is shown - it loads the html and css dynamically. The site is running on google app engine (python), and I'm under the impression that there isn't a python API for less compilation on the server. Next port of call might be using an external server and sending the compilation task to it, but would rather not go to that extent if possible - less.js comes pretty close to solving the problem. – hawkett Jul 04 '10 at 20:27

4 Answers4

30

I just pushed 1.0.31 — it has a method: less.refreshStyles() which will re-compile <style> tags with type="text/less" — try it out and let me know if it works.

cloudhead
  • 15,253
  • 6
  • 42
  • 37
  • Hi - thanks for the response. I should have mentioned that the css is loaded by dynamically appending the into the document head - so it is not included in – hawkett Jul 05 '10 at 15:17
  • I did a quick test of both these methods - firstly the dynamically added tag - the issue I am having is that I don't seem to be able to append a style tag with type='text/less' (using jquery) - it always reverts to 'text/css' in both firefox and chrome. I can see a style tag for a document loaded with that has id='less:static-less-style', but it too has a type of 'text/css', so it doesn't look jQuery related. For the second approach using less.refresh() - I can't get this to work for s to less documents in the head that appear after the less.js script import. – hawkett Jul 05 '10 at 16:16
  • Apologies - I misread your last comment - less.sheets.push() works great - I've edited the code in the original question to show it working - thanks. – hawkett Jul 05 '10 at 16:31
  • 2
    Out of interest, is it possible to process a single sheet without refreshing everything - e.g. less.sheets.push(mySheet); less.loadStyleSheet(mySheet); ? For my use-case existing sheets never have dependencies on newly loaded sheets... – hawkett Jul 05 '10 at 16:54
  • @cloudhead, can you tell how to import less instance in React? I mean, before you invoke less.refreshStyles() you need a instance of less . where the instance comes from ? – jjzjx118_2 May 05 '21 at 15:45
11

thanks for asking this question – it helped me a lot. I’m just updating the topic in order to show how I did to dynamically add a CSS file.

I used the last version of LESS (1.3.3).

var stylesheetFile = 'file.css';
var link  = document.createElement('link');
link.rel  = "stylesheet";
link.type = "text/less";
link.href = stylesheetFile;
less.sheets.push(link);

less.refresh();
St3ph
  • 111
  • 1
  • 3
  • can I know where the less instance comes from ? I am using React. I mean.. you must import less from somewhere ,right? – jjzjx118_2 May 05 '21 at 15:43
1

You can use this lightweight (3k) library to lazy load less / css and js files ( disclaimer: i am the author).

This is as simple as:

lazy.load('/static/less/style.less');

It can also receive a callback, load some more assets with dependencies and takes care about cache.

Oren Yakobi
  • 279
  • 1
  • 4
  • 14
1

I found an up-to-date version of the script that works perfect with LESS file:

  <script src="//cdnjs.cloudflare.com/ajax/libs/less.js/3.0.0/less.min.js"></script>

Instead using

less.refreshStyles()

use

less.refresh()
sapir
  • 11
  • 3