Less
安装
npm
sudo npm install -g less
测试,建立文件styles.less
:
@base: #f938ab; .box-shadow(@style, @c) when (iscolor(@c)) { -webkit-box-shadow: @style @c; box-shadow: @style @c; } .box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) { .box-shadow(@style, rgba(0, 0, 0, @alpha)); } .box { color: saturate(@base, 5%); border-color: lighten(@base, 30%); div { .box-shadow(0 0 5px, 30%) } }
编译
参数:
-
-x
压缩 -
--clean-css
启用clean css进行压缩
编译成css:
lessc styles.less > styles.css
查看结果:
.box { color: #fe33ac; border-color: #fdcdea; } .box div { -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); }
Rhino
在1.7版本以前的 less.js 同样包含了 rhino-compatible 版本。
命令行 rhino 版本需要包含以下两个文件:
- less-rhino-.js - 编译执行,
- lessc-rhino-.js - 命令行支持
命令行执行编译:
java -jar js.jar -f less-rhino-<version>.js lessc-rhino-<version>.js styles.less styles.css
以上将编译 styles.less 文件并保存为 styles.css 文件。 输出文件的参数是可选的,如果没有指定该参数,less将默认输出到标准输出中(stdout)。
代码中调用
可以像下面这样在代码中调用 Less 编译器(Node 平台)。
var less = require('less'); less.render('.class { width: (1 + 1) }', function (e, css) { console.log(css); });
输出为
.class { width: 2; }
你还可以手动调用分析器(paser)和编译器:
var parser = new(less.Parser); parser.parse('.class { width: (1 + 1) }', function (err, tree) { if (err) { return console.error(err) } console.log(tree.toCSS()); });
可以给编译器传递多个参数:
var parser = new(less.Parser)({ paths: ['.', './lib'], // Specify search paths for @import directives filename: 'style.less' // Specify a filename, for better error messages }); parser.parse('.class { width: (1 + 1) }', function (e, tree) { tree.toCSS({ // Minify CSS output compress: true }); });
浏览器中使用
提示
- 在浏览器上跑 less.js 非常方便开发,但是不推荐用于生产环境。
-
务必确保在
less.js
之前加载你的样式表。 -
如果加载多个
.less
样式表文件,每个文件都会被单独编译。 因此,一个文件中所定义的任何变量、mixin或命名空间都无法在其它文件中访问。
先写less样式文件:
<link rel="stylesheet/less" type="text/css" href="styles.less" />
接下来,加载less.js
,必须放在head
内的script
中:
<script src="less.js" type="text/javascript"></script>
也可以用CDN:
<script src="http://cdn.bootcss.com/less.js/1.7.0/less.min.js"></script>
语法
变量
请注意 LESS 中的变量为完全的「常量」 ,所以只能定义一次:
@nice-blue: #5B83AD; @light-blue: @nice-blue + #111; #header { color: @light-blue; }
输出:
#header { color: #6c94be; }
甚至可以用变量名定义为变量:
@fnord: "I am fnord."; @var: 'fnord'; content: @@var;
解析后:
content: "I am fnord.";
混合
任何CSS的class
, id
或者元素
的属性都可以复用,而不用写多遍重复的代码。
例如已经有一个类bordered
:
.bordered { border-top: dotted 1px black; border-bottom: solid 2px black; }
其他的类可以直接包含它的属性,不用再重写一遍:
#menu a { color: #111; .bordered; } .post a { color: red; .bordered; }
输出结果:
#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; }
带参数的混合
/* 参数 */ .border-radius (@radius) { border-radius: @radius; -moz-border-radius: @radius; -webkit-border-radius: @radius; } /* 调用 */ #header { .border-radius(4px); } .button { .border-radius(6px); }
还可以设置默认值:
.border-radius (@radius: 5px) { border-radius: @radius; -moz-border-radius: @radius; -webkit-border-radius: @radius; } #header { .border-radius; }
隐藏无参数样式
带括号但是没有参数,可以防止把这个样式生成到css里:
.wrap () { text-wrap: wrap; white-space: pre-wrap; white-space: -moz-pre-wrap; word-wrap: break-word; } pre { .wrap }
输出:
pre { text-wrap: wrap; white-space: pre-wrap; white-space: -moz-pre-wrap; word-wrap: break-word; }
arguments 变量
@arguments
包含了所有传递进来的参数:
.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);
输出:
box-shadow: 2px 5px 1px #000; -moz-box-shadow: 2px 5px 1px #000; -webkit-box-shadow: 2px 5px 1px #000;
模式匹配
定义不同的模式:
.mixin (dark, @color) { color: darken(@color, 10%); } .mixin (light, @color) { color: lighten(@color, 10%); } .mixin (@_, @color) { display: block; }
使用时指定要用哪一个:
@switch: light; .class { .mixin(@switch, #888); }
输出:
.class { color: #a2a2a2; display: block; }
不光参数的值,参数个数也可以用来匹配。如,只有一个参数是匹配第一个, 如果有第二个参数就匹配第二个:
.mixin (@a) { color: @a; } .mixin (@a, @b) { color: fade(@a, @b); }
引导
导引中可用的全部比较运算有:>
、>=
、=
、=<
、<
。
此外,关键字true
只表示布尔真值。
.mixin (@a) when (lightness(@a) >= 50%) { background-color: black; } .mixin (@a) when (lightness(@a) < 50%) { background-color: white; } .mixin (@a) { color: @a; }
根据参数的值进行匹配,如:
.class1 { .mixin(#ddd) } .class2 { .mixin(#555) }
就会得到:
.class1 { background-color: black; color: #ddd; } .class2 { background-color: white; color: #555; }
下面两个混合是相同的:
.truth (@a) when (@a) { ... } .truth (@a) when (@a = true) { ... }
除去关键字true
以外的值都被视示布尔假:
.class { .truth(40); // Will not match any of the above definitions. }
导引序列使用逗号,
分割,当且仅当所有条件都符合时,才会被视为匹配成功。
.mixin (@a) when (@a > 10), (@a < -10) { ... }
导引可以无参数,也可以对参数进行比较运算:
@media: mobile; .mixin (@a) when (@media = mobile) { ... } .mixin (@a) when (@media = desktop) { ... } .max (@a, @b) when (@a > @b) { width: @a } .max (@a, @b) when (@a < @b) { width: @b }
最后,如果想基于值的类型进行匹配,我们就可以使用is*
函式:
.mixin (@a, @b: 0) when (isnumber(@b)) { ... } .mixin (@a, @b: black) when (iscolor(@b)) { ... }
下面就是常见的检测函式:
- iscolor
- isnumber
- isstring
- iskeyword
- isurl
如果你想判断一个值是纯数字,还是某个单位量,可以使用下列函式:
- ispixel
- ispercentage
- isem
最后再补充一点,在导引序列中可以使用and
关键字实现与条件:
.mixin (@a) when (isnumber(@a)) and (@a > 0) { ... }
使用not
关键字实现或条件
.mixin (@b) when not (@b > 0) { ... }
嵌套规则
#header { color: black; .navigation { font-size: 12px; } .logo { width: 300px; &:hover { text-decoration: none } } }
输出:
#header { color: black; } #header .navigation { font-size: 12px; } #header .logo { width: 300px; } #header .logo:hover { text-decoration: none; }
注意&
符号的使用:如果你想写串联选择器,而不是写后代选择器,就可以用到&
了。
这点对伪类尤其有用如:hover
和:focus
。例如:
.bordered { &.float { float: left; } .top { margin: 5px; } }
会输出
.bordered.float { float: left; } .bordered .top { margin: 5px; }
运算
任何数字、颜色或者变量都可以参与运算:
@base: 5%; @filler: @base * 2; @other: @base + @filler; color: #888 / 4; background-color: @base-color + #111; height: 100% / 2 + @filler;
LESS 的运算已经超出了我们的期望,它能够分辨出颜色和单位。 如果像下面这样单位运算的话:
@var: 1px + 5; /* LESS 会输出 6px. */ width: (@var + 5) * 2; /* 括号也同样允许使用 */ border: (@width * 2) solid black; /* 并且可以在复合属性中进行运算 */
Color 函数
LESS 提供了一系列的颜色运算函数. 颜色会先被转化成 HSL 色彩空间, 然后在通道级别操作:
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 fade(@color, 50%); // return @color with 50% transparency 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 @color mix(@color1, @color2); // return a mix of @color1 and @color2
使用起来相当简单:
@base: #f04615; .class { color: saturate(@base, 5%); background-color: lighten(spin(@base, 8), 25%); }
你还可以提取颜色信息:
hue(@color); // returns the `hue` channel of @color saturation(@color); // returns the `saturation` channel of @color lightness(@color); // returns the 'lightness' channel of @color
如果你想在一种颜色的通道上创建另一种颜色,这些函数就显得那么的好用,例如:
@new: hsl(hue(@old), 45%, 90%);
@new
将会保持@old
的色调,但是具有不同的饱和度和亮度。
Math 函数
LESS提供了一组方便的数学函数,你可以使用它们处理一些数字类型的值:
round(1.67); // returns `2` ceil(2.4); // returns `3` floor(2.6); // returns `2`
如果你想将一个值转化为百分比,你可以使用percentage
函数:
percentage(0.5); // returns `50%`
命名空间
有时候,你可能为了更好组织CSS或者单纯是为了更好的封装,
将一些变量或者混合模块打包起来,
你可以像下面这样在#bundle
中定义一些属性集之后可以重复使用:
#bundle { .button () { display: block; border: 1px solid black; background-color: grey; &:hover { background-color: white } } .tab { ... } .citation { ... } }
你只需要在#header a
中像这样引入.button
:
#header a { color: orange; #bundle > .button; }
作用域
LESS 中的作用域跟其他编程语言非常类似,首先会从本地查找变量或者混合模块, 如果没找到的话会去父级作用域中查找,直到找到为止:
@var: red; #page { @var: white; #header { color: @var; }// white } #footer { color: @var; // red }
注释
CSS 形式的注释在 LESS 中是依然保留的:
/* Hello, I'm a CSS-style comment */ .class { color: black }
LESS 同样也支持双斜线的注释, 但是编译成 CSS 的时候自动过滤掉:
// Hi, I'm a silent comment, I won't show up in your CSS .class { color: white }
Importing
你可以在main文件中通过下面的形势引入.less
文件,.less
后缀可带可不带:
@import "lib.less"; @import "lib";
如果你想导入一个CSS文件而且不想LESS对它进行处理,只需要使用.css
后缀就可以:
@import "lib.css";
这样LESS就会跳过它不去处理它.
字符串插值
变量可以用类似ruby和php的方式嵌入到字符串中,像@{name}
这样的结构:
@base-url: "http://assets.fnord.com"; background-image: url("@{base-url}/../wiki_images/bg.png");
避免编译
有时候我们需要输出一些不正确的CSS语法或者使用一些 LESS不认识的专有语法。
要输出这样的值我们可以在字符串前加上一个~
,例如:
.class { filter: ~"ms:alwaysHasItsOwnSyntax.For.Stuff()"; }
我们可以将要避免编译的值用""
包含起来,输出结果为:
.class { filter: ms:alwaysHasItsOwnSyntax.For.Stuff(); }
JavaScript 表达式
JavaScript 表达式也可以在.less
文件中使用。可以通过反引号的方式使用:
@var: `"hello".toUpperCase() + '!'`;
输出:
@var: "HELLO!";
注意你也可以同时使用字符串插值和避免编译:
@str: "hello"; @var: ~`"@{str}".toUpperCase() + '!'`;
输出:
@var: HELLO!;
它也可以访问JavaScript环境:
@height: `document.body.clientHeight`;
如果你想将一个JavaScript字符串解析成16进制的颜色值, 你可以使用 color 函数:
@color: color(`window.colors.baseColor`); @darkcolor: darken(@color, 10%);