As an extension to CSS, LESS is not only backwards compatible with CSS, but the extra features it adds use existing CSS syntax. This makes learning LESS a breeze, and if in doubt, lets you fall back to CSS.
Variables
These are pretty self-explanatory:
@nice-blue: #5B83AD; @light-blue: @nice-blue + #111; #header { color: @light-blue; }Outputs:
#header { color: #6c94be; }It is also possible to define variables with a variable name:
@fnord: "I am fnord."; @var: 'fnord'; content: @@var;Which compiles to:
content: "I am fnord.";Note that variables in LESS are actually ‘constants’ in that they can only be defined once.
Mixins
In LESS, it is possible to include a bunch of properties from one ruleset into another ruleset. So say we have the following class:
.bordered { border-top: dotted 1px black; border-bottom: solid 2px black; }And we want to use these properties inside other rulesets. Well, we just have to drop in the name of the class in any ruleset we want to include its properties, like so:
#menu a { color: #111; .bordered; } .post a { color: red; .bordered; }The properties of the
.bordered
class will now appear in both#menu a
and.post a
:#menu a { color: #111; border-top: dotted 1px black; border-bottom: solid 2px black; } .post a { color: red; border-top: dotted 1px black; border-bottom: solid 2px black; }Any CSS class, id or element ruleset can be mixed-in that way.
Parametric Mixins
LESS has a special type of ruleset which can be mixed in like classes, but accepts parameters. Here’s the canonical example:
.border-radius (@radius) { border-radius: @radius; -moz-border-radius: @radius; -webkit-border-radius: @radius; }And here’s how we can mix it into various rulesets:
#header { .border-radius(4px); } .button { .border-radius(6px); }Parametric mixins can also have default values for their parameters:
.border-radius (@radius: 5px) { border-radius: @radius; -moz-border-radius: @radius; -webkit-border-radius: @radius; }We can invoke it like this now:
#header { .border-radius; }And it will include a 5px border-radius.
You can also use parametric mixins which don’t take parameters. This is useful if you want to hide the ruleset from the CSS output, but want to include its properties in other rulesets:
.wrap () { text-wrap: wrap; white-space: pre-wrap; white-space: -moz-pre-wrap; word-wrap: break-word; } pre { .wrap }Which would output:
pre { text-wrap: wrap; white-space: pre-wrap; white-space: -moz-pre-wrap; word-wrap: break-word; }The
@arguments
variable
@arguments
has a special meaning inside mixins, it contains all the arguments passed, when the mixin was called. This is useful if you don’t want to deal with individual parameters:.box-shadow (@x: 0, @y: 0, @blur: 1px, @color: #000) { box-shadow: @arguments; -moz-box-shadow: @arguments; -webkit-box-shadow: @arguments; } .box-shadow(2px, 5px);Which results in:
box-shadow: 2px 5px 1px #000; -moz-box-shadow: 2px 5px 1px #000; -webkit-box-shadow: 2px 5px 1px #000;Nested rules
LESS gives you the ability to use nesting instead of, or in combination with cascading. Lets say we have the following CSS:
#header { color: black; } #header .navigation { font-size: 12px; } #header .logo { width: 300px; } #header .logo:hover { text-decoration: none; }In LESS, we can also write it this way:
#header { color: black; .navigation { font-size: 12px; } .logo { width: 300px; &:hover { text-decoration: none } } }Or this way:
#header { color: black; .navigation { font-size: 12px } .logo { width: 300px; &:hover { text-decoration: none } } }The resulting code is more concise, and mimics the structure of your
DOM tree
.Notice the
&
combinator—it’s used when you want a nested selector to be concatinated to its parent selector, instead of acting as a descendent. This is especially important for pseudo-classes like:hover
and:focus
.For example:
.bordered { &.float { float: left; } .top { margin: 5px; } }Will output
.bordered.float { float: left; } .bordered .top { margin: 5px; }Operations
Any number, color or variable can be operated on. Here are a couple of examples:
@base: 5%; @filler: @base * 2; @other: @base + @filler; color: #888 / 4; background-color: @base-color + #111; height: 100% / 2 + @filler;The output is pretty much what you expect—LESS understands the difference between colors and units. If a unit is used in an operation, like in:
@var: 1px + 5;LESS will use that unit for the final output—
6px
in this case.Brackets are also authorized in operations:
width: (@var + 5) * 2;And are required in compound values:
border: (@width * 2) solid black;Color functions
LESS provides a variety of functions which transform colors. Colors are first converted to the HSL color-space, and then manipulated at the channel level:
lighten(@color, 10%); // return a color which is 10% *lighter* than @color darken(@color, 10%); // return a color which is 10% *darker* than @color saturate(@color, 10%); // return a color 10% *more* saturated than @color desaturate(@color, 10%); // return a color 10% *less* saturated than @color fadein(@color, 10%); // return a color 10% *less* transparent than @color fadeout(@color, 10%); // return a color 10% *more* transparent than @color spin(@color, 10); // return a color with a 10 degree larger in hue than @color spin(@color, -10); // return a color with a 10 degree smaller hue than @colorUsing them is pretty straightforward:
@base: #f04615; .class { color: saturate(@base, 5%); background-color: lighten(spin(@base, 8), 25%); }You can also extract color information:
hue(@color); // returns the `hue` channel of @color saturation(@color); // returns the `saturation` channel of @color lightness(@color); // returns the 'lightness' channel of @colorThis is useful if you want to create a new color based on another color’s channel, for example:
@new: hsl(hue(@old), 45%, 90%);
@new
will have@old
’s hue, and its own saturation and lightness.Namespaces
Sometimes, you may want to group your variables or mixins, for organizational purposes, or just to offer some encapsulation. You can do this pretty intuitively in LESS—say you want to bundle some mixins and variables under
#bundle
, for later re-use, or for distributing:#bundle { .button () { display: block; border: 1px solid black; background-color: grey; &:hover { background-color: white } } .tab { ... } .citation { ... } }Now if we want to mixin the
.button
class in our#header a
, we can do:#header a { color: orange; #bundle > .button; }Scope
Scope in LESS is very similar to that of programming languages. Variables and mixins are first looked up locally, and if they aren’t found, the compiler will look in the parent scope, and so on.
@var: red; #page { @var: white; #header { color: @var; // white } } #footer { color: @var; // red }Comments
CSS-style comments are preserved by LESS:
/* Hello, I'm a CSS-style comment */ .class { color: black }Single-line comments are also valid in LESS, but they are ‘silent’, they don’t show up in the compiled CSS output:
// Hi, I'm a silent comment, I won't show up in your CSS .class { color: white }Importing
You can import
.less
files, and all the variables and mixins in them will be made available to the main file. The.less
extension is optional, so both of these are valid:@import "lib.less"; @import "lib";If you want to import a CSS file, and don’t want LESS to process it, just use the
.css
extension:@import "lib.css";The directive will just be left as is, and end up in the CSS output.
String interpolation
Variables can be embeded inside strings in a similar way to ruby or PHP, with the
@{name}
construct:@base-url: "http://assets.fnord.com"; background-image: url("@{base-url}/images/bg.png");Escaping
Sometimes you might need to output a CSS value which is either not valid CSS syntax, or uses propriatery syntax which LESS doesn’t recognize.
To output such value, we place it inside a string prefixed with
~
, for example:.class { filter: ~"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='image.png')"; }This is called an “escaped value”, which will result in:
.class { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='image.png'); }JavaScript evaluation
JavaScript expressions can be evaluated as values inside .less files. This is done by wrapping the expression with back-ticks:
@var: `"hello".toUpperCase() + '!'`;Becomes:
@var: "HELLO!";Note that you may also use interpolation and escaping as with strings:
@str: "hello"; @var: ~`"@{str}".toUpperCase() + '!'`;Becomes:
@var: HELLO!;It is also possible to access the JavaScript environment:
@height: `document.body.clientHeight`;
Thursday, September 22, 2011
LESS « The Dynamic Stylesheet language - Whose playing with this? - Besides Twitter
via lesscss.org
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment