作为CSS的一种扩展,LESSCSS不仅向下兼容CSS的语法,而且连新增的特性也是使用CSS的语法。这样的设计使得学习LESS很轻松,而且你可以在任何时候回退到CSS。
变量
很容易理解:
@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的机制类似,最后一次定义的值会成为这个属性的值。
比如:
@var:
0;
.class1 {
@var
:
1;
.class
{
@var
:
2;
three
:
@var;
@var
:
3;
}
one
:
@var;
}
会编译成:
.class1.class {
three
:
3;
}
.class1 {
one
:
1;
}
变量是“按需加载”(lazyloaded)的,因此不必强制在使用之前声明。
下面是一个有效的LESS代码片段:
lazy-
eval{
width
:
@var;
}
@var:
@a;
@a:
9%;
下面这个片段也是有效的:
.lazy-eval-scope {
width
:
@var;
@a
:
9%;
}
@var:
@a;
@a:
100%;
这两个片段都会编译成:
.lazy-eval-scope {
width
:
9%;
}
混合(Mixins)
在 LESS 中我们可以定义一些通用的属性集为一个 class,然后在另一个 class 中去调用这些属性,下面有这样一个 class:
.bordered {
border-top
: dotted
1pxblack;
border-bottom
: solid
2pxblack;
}
那如果我们现在需要在其他class 中引入那些通用的属性集,那么我们只需要在任何class 中像下面这样调用就可以了:
#menua {
color
:
#111;
.bordered
;
}
.posta {
color
: red;
.bordered
;
}
.bordered
class里面的属性样式都会在 #menu a
和 .post a
中体现出来:
#menua {
color
:
#111;
border-top
: dotted
1pxblack;
border-bottom
: solid
2pxblack;
}
.posta {
color
: red;
border-top
: dotted
1pxblack;
border-bottom
: solid
2pxblack;
}
任何 CSSclass, id 属性集都可以以同样的方式引入。
注意:变量也会被混合,也就是说变量会被带到当前的作用域。这个特性还有争议,也许在未来会有变化。
带参数混合
在 LESS 中,你还可以像函数一样定义一个带参数的属性集合:
.border-radius(
@radius) {
border-radius
:
@radius;
-moz-border-radius
:
@radius;
-webkit-border-radius
:
@radius;
}
然后在其他class 中像这样调用它:
#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
;
}
radius
的值就会是 5px。
你也可以定义不带参数属性集合,如果你想隐藏这个属性集合,不让它暴露到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;
}
多参数混合
多个参数可以使用分号或者逗号分隔,推荐使用分号分隔,因为逗号有两重含义:它既可以表示混合的参数,也可以表示一个参数中一组值的分隔符。
使用分号作为参数分隔符意味着可以将逗号分隔的一组值作为一个变量处理。换句话说,如果编译器在混合的定义或者是调用中找到至少一个分号,就会假设参数是使用分号分隔的,所有的逗号都属于参数中的一组值的分隔符。
2个参数,每个参数都含有通过逗号分隔的一组值的情况:.name(
1,
2,
3; something, else)
。
3个参数,每个参数只含一个数字的情况:.name(
1,
2,
3)
。
使用一个象征性的分号可以创建一个只含一个参数,但参数包含一组值的混合:.name(
1,
2,
3;)
。
逗号分隔的一组值参数的默认值:.name(
@param1: red, blue;)
。
使用同样的名字和同样数量的参数定义多个混合是合法的。在被调用时,LESS会应用到所有可以应用的混合上。比如你调用混合时只传了一个参数.mixin(green)
,那么所有只强制要求一个参数的混合都会被调用:
.mixin(
@color) {
color
-1:
@color;
}
.mixin(
@color;
@padding:
2) {
color
-2:
@color;
padding
-2:
@padding;
}
.mixin(
@color;
@padding;
@margin:
2) {
color
-3:
@color;
padding
-3:
@padding;
margin
:
@margin @margin @margin @margin;
}
.some.selectordiv {
.mixin
(
#008000);
}
编译结果:
.some.selectordiv {
color
-1:
#008000;
color
-2:
#008000;
padding
-2:
2;
}
@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:
2px5px1px#000;
-moz-box-shadow:
2px5px1px#000;
-webkit-box-shadow:
2px5px1px#000;
高级参数用法与 @rest 变量
如果需要在mixin 中不限制参数的数量,可以在变量名后添加...,表示这里可以使用 N 个参数。
.mixin (...) {
// 接受 0-N 个参数
.mixin () {
// 不接受任何参数
.mixin(
@a:
1) {
// 接受 0-1 个参数
.mixin(
@a:
1, ...) {
// 接受 0-N 个参数
.mixin(
@a, ...) {
// 接受 1-N 个参数
此外:
.mixin(
@a,
@rest...) {
// @rest 表示 @a 之后的参数
// @arguments 表示所有参数
}
!important关键字
调用时在混合后面加上!important关键字表示将混合带来的所有属性标记为!important:
.mixin(
@a:
0) {
border
:
@a;
boxer
:
@a;
}
.unimportant {
.mixin
(
1);
}
.important {
.mixin
(
2)
!important;
}
编译成:
.unimportant {
border
:
1;
boxer
:
1;
}
.important {
border
:
2!important;
boxer
:
2!important;
}
模式匹配与Guard表达式
LESS 提供了通过参数值控制 mixin 行为的功能,让我们先从最简单的例子开始:
.mixin(
@s,
@color) { ... }
.class {
.mixin
(
@switch,
#888);
}
如果要根据 @switch 的值控制 .mixin
行为,只需按照下面的方法定义 .mixin
:
.mixin(dark,
@color) {
color
: darken(
@color,
10%);
}
.mixin(light,
@color) {
color
: lighten(
@color,
10%);
}
.mixin(
@_,
@color) {
display
: block;
}
然后调用:
@switch: light;
.class {
.mixin
(
@switch,
#888);
}
将会得到以下CSS:
.class {
color
:
#a2a2a2;
display
: block;
}
传给 .mixin
的颜色将执行 lighten
函数,如果 @switch 的值是 dark
,那么则会执行 darken
函数输出颜色。
以下是整个过程如何发生的:
- 第一个
.mixin
没有匹配,因为不满足dark
条件; - 第二个
.mixin
可以被匹配,因为它满足了light
条件; - 第三个
.mixin
也可以被匹配,因为它接受任何参数。
只有满足匹配要求的混合才会被使用。混合中的变量可以匹配任何值,非变量形式的值只有与传入的值完全相等时才可以匹配成功。
我们也可以根据参数的数量进行匹配,比如:
.mixin(
@a) {
color
:
@a;
}
.mixin(
@a,
@b) {
color
: fade(
@a,
@b);
}
调用 .mixin
时,如果使用了一个参数,输出第一个 .mixin
,使用了两个参数,则输出第二个。
Guards
与上面匹配值或者匹配参数数量的情况不同,Guards被用来匹配表达式 (expressions)。如果你很熟悉编程函数的用法,那么很可能你已经掌握它的用法了。
为了尽可能地符合CSS 的语言结构,LESS 选择使用 guard混合(guarded mixins)(类似于 @media 的工作方式)执行条件判断,而不是加入 if/else
声明。
首先通过下面的例子开始介绍:
.mixin(
@a) when (lightness(
@a) >=
50%) {
background-color
: black;
}
.mixin(
@a) when (lightness(
@a) <
50%) {
background-color
: white;
}
.mixin(
@a) {
color
:
@a;
}
要点在于关键词 when
,它引入了一个guard 条件(这里只用到一个 guard)。现在如果运行下面的代码:
.class1{
.mixin(
#ddd) }
.class2{
.mixin(
#555) }
将会得到以下输出结果:
.class1 {
background-color
: black;
color
:
#ddd;
}
.class2 {
background-color
: white;
color
:
#555;
}
Guards 支持的运算符包括:>
>=
=
=<
<
。说明一下,true
关键字是唯一被判断为真的值,也就是这两个混合是相等的:
.truth(
@a) when (
@a) { ... }
.truth(
@a) when (
@a= true) { ... }
其他不为 true
的值都判为假:
.class {
.truth
(
40);
// 不会匹配上面的 mixin
}
多个Guards可以通过逗号表示分隔,如果其中任意一个结果为 true
,则匹配成功:
.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
在 guard
中加入额外的条件:
.mixin (@a) when (isnumber(@a))and (@a > 0) { ... }
或者,使用关键词 not
否定条件:
.mixin (@b) when not (@b > 0) {... }
嵌套规则
LESS 可以让我们以嵌套的方式编写层叠样式。让我们先看下下面这段CSS:
#header{
color: black; }
#header.navigation {
font-size:
12px;
}
#header.logo {
width:
300px;
}
#header.logo:hover {
text-decoration: none;
}
在 LESS 中, 我们就可以这样写:
#header {
color
: black;
.navigation
{
font-size
:
12px;
}
.logo
{
width
:
300px;
&
:hover{
text-decoration: none }
}
}
或者这样写:
#header{
color: black;
.navigation
{
font-size:
12px}
.logo
{
width:
300px;
&
:hover{
text-decoration: none }
}
}
代码更简洁了,而且感觉跟DOM 结构格式有点像。
注意 &
符号的使用 — 如果你想写串联选择器,而不是写后代选择器,就可以用到 &
了。这点对伪类尤其有用如:hover
和 :focus
。
例如:
.bordered {
&
.float{
float
: left;
}
.top
{
margin
:
5px;
}
}
会输出:
.bordered.float {
float
: left;
}
.bordered.top {
margin
:
5px;
}
嵌套Media Queries
Media query也可以使用同样的方式进行嵌套。
.one {
@media
(width:
400px) {
font-size
:
1.2em;
@media printandcolor
{
color
: blue;
}
}
}
输出:
@media(width:
400px) {
.one
{
font-size
:
1.2em;
}
}
@media(width:
400px)
andprintandcolor{
.one
{
color
: blue;
}
}
&
的高级用法
用在选择器中的&
还可以反转嵌套的顺序并且可以应用到多个类名上。
例如:
.child,
.sibling{
.parent
& {
color
: black;
}
& + & {
color
: red;
}
}
输出:
.parent.child,
.parent.sibling {
color
: black;
}
.child+
.child,
.child+
.sibling,
.sibling+
.child,
.sibling+
.sibling{
color
: red;
}
&
也可以用在混合中用于指示嵌套这个混合的父选择器。
运算
任何数字、颜色或者变量都可以参与运算,运算应该被包裹在括号中。来看一组例子:
@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);