Programmatically Editing Less (Css) Code with Jquery-Like Selector Syntax

Change LESSCSS variable with jQuery

Instead of dinamically changing values in your less file - which is impossible on the client side (aka JavScript), try creating multiple variants in less (something like a theme), and then apply a custom class to an element (body works well).

For example,

[style.less]
@green: #00EE00;
@blue: #0000EE;

body {
&.green { background:@green }
&.blue { background:@blue }
}

[main.js]
$('#id').on('click', 'a.blue', function() {
$('body').removeClass('green').addClass('blue')
}

Javascript library for editing LESS CSS variables?

I've come across this problem often lately and after trying many things my solution is to eventually ditch LESS and go with Stylus, which has a nice JavaScript API.

In any case, this is what I have working right now to get LESS variables in JavaScript:

var getLessVar = function (name, prop) {
var value = $('<div class="' + name + '"></div>').hide().appendTo('body').css(prop)
$('.' + name).remove()
return /^\d+/.test(value) ? +value : value
}

It's hacky but works. You create a class in LESS and assign the variable you want to get in JS to a property, let's say width, but it can be any other property, depending of the type of data you're sending (numbers, colors...)

@myvar: 30px + @foo;
.myvar { width: @myvar }

Then in JS you grab the variable with that lil' script like this:

var myvar = getLessVar('myvar', 'width')

This is not great for performance as it creates an invisible element to retrieve the data but it works.


To set a variable from JS is more complicated, but you can always do some AJAX magic together with LessPHP and some basic parser to read your variables.less.

But again, if you need more power just go with Stylus.

dynamically change LESS variables in page with JavaScript

Instead of doing the variable replacing client-side, since I was doing it in a Rails app anyway, I moved it server-side. I'm using the Ruby bindings for LESS to parse some LESS that includes my custom variables, rendering the parsed result with content_type: 'text/css' and using an AJAX request to add a stylesheet link to the rendered CSS.

Less CSS precompute number and append unit

Try the following:
(100/300)*1%

Less only accepts values and not strings so you cant just add a string after a number but you can multiply with a percentage to archieve the same.

Output nested selectors as individual lines with LESS

I found that if I just structured it like this, without the commas, I get the desired outcome.

.newsletter-form input {
&::-webkit-input-placeholder {
color: red !important;
}
&::-moz-placeholder {
color: red !important;
}
&:-ms-input-placeholder {
color: red !important;
}
}

Or using a mixin for flexibility.

.placeholder(@color) {
&::-webkit-input-placeholder {color: @color !important;}
&::-moz-placeholder {color: @color !important;}
&:-ms-input-placeholder {color: @color !important;}
}

.newsletter-form input {
.placeholder(red)
}

Compile a referenced LESS file into CSS with PHP automatically

THIS ASSUMES LESSPHP v0.3.8+ Unsure about earlier versions, but you'll get the gist of how it works if it doesn't straight out of the box.

<link rel="stylesheet" type="text/css" href="styles/main.less" />

If you were using less.js to compile client side, make sure you change rel="stylesheet/less" to rel="stylesheet"

1) Grab Lessphp I placed these files in /www/compilers/lessphp/ for the context of this demo

2) Make a PHP script that we can throw out LESS files at. This will deal with caching, compiling to CSS and returning the CSS as a response. I have placed this file at /www/compilers/ and called it lessphp.php

Most of this code was on the Lessphp site, except there were errors in it, and I have added the response at the end.

<?php
require "lessphp/lessc.inc.php";
$file = $_GET["file"];
function autoCompileLess($inputFile, $outputFile) {
// load the cache
$cacheFile = $inputFile.".cache";
if (file_exists($cacheFile)) {
$cache = unserialize(file_get_contents($cacheFile));
} else {
$cache = $inputFile;
}
$less = new lessc;
$less->setFormatter("compressed");
$newCache = $less->cachedCompile($cache);
if (!is_array($cache) || $newCache["updated"] > $cache["updated"]) {
file_put_contents($cacheFile, serialize($newCache));
file_put_contents($outputFile, $newCache['compiled']);
}
}
autoCompileLess('../' . $file, '../' . $file . '.css');
header('Content-type: text/css');
readfile('../' . $file . '.css');
?>

This will compile the LESS file (eg, styles/main.less) to a cache file and a CSS file (eg, styles/main.less.css).

3) Add a mod_rewrite rule so that any LESS files a user requests are redirected to our compiler, giving it its path. This was placed in the root .htaccess file.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^([^.]*\.less)$ compilers/lessphp.php?file=$1 [R,QSA,L]
</ifModule>

If you are using WordPress, this rule will need to come after it - even if WordPress is in a sub directory, it seems to overwrite these rules, and LESS compilation will not occur for referenced files which exist below (directory wise) WordPress's .htaccess rules.

4) Your LESS code should be relatively referenced in relation to the compilers location. Additionally, Lessphp compiler will fail if there are empty attributes, eg. background-color: ;


If all is working well, the following should occur:

  1. Directly browse your LESS file http://domain.com/styles/main.less

  2. Be automatically redirected to http://domain.com/compilers/lessphp?file=styles/main.less

  3. Be presented with minified CSS

  4. main.less.css and main.less.cache should now exist in the same directory as your LESS file

  5. The last modified dates shouldn’t change unless you update your LESS file

Access CSS file contents via JavaScript

you could load the content with a simple ajax get call, if stylesheet is included from the same domain

Edit after your update:
I tried this code (on FX10) as a proof of concept that uses only one request to the CSS but it seems a bit hacky to me and should be tested and verified. it also should be improved with some fallback if javascript is not available.

CSS (external file test.css)

div { border: 3px solid red;}

HTML/jQuery

<!doctype html >
<html>
<head>
<!-- provide a fallback if js not available -->
<noscript>
<link rel="stylesheet" href="test.css" />
</noscript>
</head>
<body>

<div></div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.js"></script>
<script>
$(document).ready(function() {

$.when($.get("test.css"))
.done(function(response) {
$('<style />').text(response).appendTo($('head'));
$('div').html(response);
});
})
</script>
</body>
</html>

You should see the CSS code inside the div with a red border all around :)

Enjoy.



Related Topics



Leave a reply



Submit