less 语法
1 变量 less的变量使用@开头
1.1 demo
@colorRed:red;
@colorBlue:blue;
.demo{
color:@colorRed;
background-color:@colorBlue;
}
对应的css:
.demo{
color:red;
baclground-color:blue;
}
1.2 甚至可以在定义变量值时使用其它的变量:
@name:"zhang san";
@info:"name";
.demo11{
&:after{
content:@@info;
}
}
对应的css:
.demo11:after {
content: "zhang san";
}
1.3 如果对同一个变量定义两次的话,在当前作用域中最后一次定义的将被使用。这与CSS的机制类似,最后一次定义的值会成为这个属性的值
1.4 变量是“按需加载”(lazy loaded)的,因此不必强制在使用之前声明。
demo1:
@var: 0;
.class1 {
@var: 1;
.class {
@var: 2;
three: @var;
@var: 3;
}
one: @var;
}
对应的css:
.class1 .class {
three: 3;
}
.class1 {
one: 1;
}
demo2:
下面是一个有效的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%;
}
2 混入(mixin) 多种动态语言都支持mixins(混入)特性,它是多重继承的一种体现,在less中,混入是指在一个class引入另外一个已经定义好的class,就像class中新添加一个属性一样
2.1 继承另为一个clss的全部样式 mixn可以轻松实现classA引入到classB中,从而轻松实现classB继承classA的所有属性
demo:
.demo1{
color:red;
border:1px solid red;
background-color:blue;
}
.demo2{
font-size:20px;
.demo1;
}
对应的css是:
.demo1{ color:red; border:1px solid red; background-color:blue; } .demo2{ font-size:20px; color:red; border:1px solid red; background-color:blue; }
2.2 从上面的demo中可以看出,mixins其实是一种嵌套,它允许将一个类嵌套到另一个类中使用,被嵌入的类也可以称作变量,简单地说,mixins其实规则级别的复用;
mixins还有一种形式Parametric Mixins(混入参数),less也支持这种特性:
demo:
border(@borderWidth){
border:@borerWidth solid red;
}
.demo3{
.border(2px);
}
.demo4{
.border(4px);
}
对应的css
.demo3{
border:2px solid red;
}
.demo4{
border:4px solid red;
}
2.3 我们还可以给mixins的参数设置一个默认值:
.borderColor(@color:red){
border:1px solid @color;
}
.demo7{
.borderColor(blue);
}
.demo8{
.borderColor;
}
对应的css:
.demo7 {
border: 1px solid blue;
}
.demo8 {
border: 1px solid red;
}
2.4 跟javascript重arguments一样,在mixins中也有这样一个变量:@arguments;@arguments在mixins中是一个很特别的参数,当mixins调用这个参数时,该参数表示所有的变量:
demo:
.boxshdow(@x,@y,@blur,@color){
-webkit-box-shadow:@arguments;
-moz-box-shadow: @arguments;
box-shadow:@arguments;
}
.demo9{
.boxshdow(0px,0px,3px,red);
}
.demo10{
.boxshdow(10px,10px,13px,blue);
}
对应的css是:
.demo9 {
-webkit-box-shadow: 0px 0px 3px red;
-moz-box-shadow: 0px 0px 3px red;
box-shadow: 0px 0px 3px red;
}
.demo10 {
-webkit-box-shadow: 10px 10px 13px blue;
-moz-box-shadow: 10px 10px 13px blue;
box-shadow: 10px 10px 13px blue;
}
2.5 可以设置默认参数:
demo:
.boxshdow(@x:0px,@y:0px,@blur:5px,@color:#000){
-webkit-box-shadow:@arguments;
-moz-box-shadow: @arguments;
box-shadow:@arguments;
}
//上面的混合也可以这样定义
.boxshdow(@x:0px,@y:0px,@blur:5px,@color:#000){
-webkit-box-shadow:@x @y @blur @color;
-moz-box-shadow: @x @y @blur @color;
box-shadow:@x @y @blur @color;
}
.demo10{
.boxshdow(10px,10px,13px,blue);
}
.demo11{
.boxshdow;
}
对应得css是:
.demo10 {
-webkit-box-shadow: 10px 10px 13px blue;
-moz-box-shadow: 10px 10px 13px blue;
box-shadow: 10px 10px 13px blue;
}
.demo11 {
-webkit-box-shadow: 0px 0px 5px #000;
-moz-box-shadow: 0px 0px 5px #000;
box-shadow: 0px 0px 5px #000;
}
2.6 如果你想隐藏这个属性集合,不让它暴露在css中,但是还想在别的属性中进行引用,就可以设置不带参数的属性集合:
demo:
.fontSize(){
font-size:20px;
}
.demo12{
.fontSize;
}
对应的css:
.demo12 {
font-size: 20px;
}
2.7使用同样的名字和同样数量的参数定义多个混合是合法的。在被调用时,LESS会应用到所有可以应用的混合上。比如你调用混合时只传了一个参数.mixin(green)
,那么所有只强制要求一个参数的混合都会被调用:
.mixin(@color) {//接受一个参数
color-1: @color;
}
.mixin(@color; @padding:2) {//接受1-2和参数,第二个参数有默认值
color-2: @color;
padding-2: @padding;
}
.mixin(@color; @padding; @margin: 2) {//接受2-3个参数,第三个参数有默认值
color-3: @color;
padding-3: @padding;
margin: @margin @margin @margin @margin;
}
.some .selector div {//会继承.mixin(@color)和.mixin(@color; @padding:2) 的样式
.mixin(#008000); }
对应的css:
.some .selector div {
color-1: #008000;
color-2: #008000;
padding-2: 2;
}
3 命名空间
为了防止多人协同开发,命名冲突的问题,可以设置命名空间
demo:
#myNameSpace{
.home{}
.user{}
}
这样我们就定义了一个名为namespace的命名空间,如果我们需要复用user这个选择器的时候,只需要在需要混入这个选择器的地方这样使用就可以了#myNameSpace>.user
4 嵌套
demo:
.container{
background-color:#fff;
color:#666;
.header{
background-color: blue;
font-size:20px;
ul{
list-style-type: none;
&:after{
display: table;
clear: both;
content:"";
}
li{
float: left;
width:25%;
}
}
}
}
对应的css:
.container {
background-color: #fff;
color: #666;
}
.container .header {
background-color: blue;
font-size: 20px;
}
.container .header ul {
list-style-type: none;
}
.container .header ul:after {
display: table;
clear: both;
content: "";
}
.container .header ul li {
float: left;
width: 25%;
}
从上面的demo中我们可以看出,less的嵌套规则与HTML中的DOM结果相对应的,这样使我们的样式表书写更加简洁和有更好的可读性;同时嵌套规则使我们对伪元素的操作更加方便
5 运算与函数
demo
@init: #111111;
@transition: @init*2;
.switchColor {
color: @transition;
}
对应的css
.switchColor {
color: #222222;
}
上面的例子中使用 LESS 的 operation 是 特性,其实简单的讲,就是对数值型的 value(数字、颜色、变量等)进行加减乘除四则运算。同时 LESS 还有一个专门针对 color 的操作提供一组函数。下面是 LESS 提供的针对颜色操作的函数列表:
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
你还可以提取颜色信息:
hue(@color); // returns the `hue` channel of @color
saturation(@color); // returns the `saturation` channel of @color
lightness(@color); // returns the 'lightness' channel of @color 从颜色对象下提取亮度值,返回百分比值是0-100
使用这些函数和 JavaScript 中使用函数一样。
demo:
init: #f04615;
#body {
background-color: fadein(@init, 10%);
}
对应的css
#body {
background-color: #f04615;
}
从上面的例子我们可以发现,这组函数像极了 JavaScript 中的函数,它可以被调用和传递参数。这些函数的主要作用是提供颜色变换的功能,先把颜色转换成 HSL 色,然后在此基础上进行操作。
6 高级参数用法与 @rest
变量
.mixin (...) { // 接受 0-N 个参数
.mixin () { // 不接受任何参数
.mixin (@a: 1) { // 接受 0-1 个参数
.mixin (@a: 1, ...) { // 接受 0-N 个参数
.mixin (@a, ...) { // 接受 1-N 个参数
.mixin (@a, @rest...) {
// @rest 表示 @a 之后的参数
// @arguments 表示所有参数
}
7 !important
关键字
调用时在混合后面加上!important关键词,表示将混合带来的所有属性标记为!important
demo:
.style1(@color,@borderWidth){
color:@color;
border:@borderWidth solid @color;
}
.demo12{
.style1(red,2px) !important;
}
.demo13{
.style1(blue,3px);
}
对应的css:
.demo12 {
color: red !important;
border: 2px solid red !important;
}
.demo13 {
color: blue;
border: 3px solid blue;
}
8 模式匹配
demo:
.test1(light,@color){
color:lighten(@color,10%);
}
.test1(dark,@color){
color:darken(@color,10%);
}
.test1(@s,@color){
display: block;
}
@switch:light;
.demo15{
.test1(@switch,red);
}
对应的css
.demo15 {
color: #ff3333;
display: block;
}
上面的test1调用lighten函数,生成对应的颜色;如果@switch 是dark 就讲调用darken函数来生成颜色
上面的代码通过@switch变量来决定继承那个混合,分析过程:
.test1(light,@color)与.test1(dark,@color)第一个参数是常量,不是变量,所以之后两个参数,并且第一个参数是light继承.test1(light,@color);第一个参数是dark继承.test1(dark,@color),
.test1(@s,@color)的两个参数都是变量,可以接受任何的类型的两个参数
根据上面的信息,我们也可以根据参数的数量来进行匹配
.test1(@s){
display: block;
}
.test1(@s,@color){
display: block;
border-color:@color;
}
调用test1时,如果是一个参数就调用.test1(@s),如果是两个参数就调用.test1(@s,@color)
9 Guard表达式
与上面匹配值和匹配参数数量不同,guard被用来匹配表达式,为了尽可能的符合css的语法结构,less选择使用guard混合来实现条件判断(类似@media的工作方式),而不是加入if/else声明
9.1 demo:
.color1(@color) when(lightness(@color)>50%){
background-color: white;
}
.color1(@color) when(lightness(@color)<50%){
background-color:black;
}
.color1(@color;){
color:@color;
}
对应的css:
.demo16 {
background-color: white;
color: #fff;
}
.demo17 {
background-color: black;
color: #000;
}
9.2 Guards支持的运算符有> >= < <= 注意:true关键字是唯一被判断为真的值,也就是说下面这两种 表达方式是一样的:
.test2(@a) when(@a){
}
.test2(@a) when(@a=true){
}
其他不为true的值都判断为假
.demo18{
.test2(40);//不会匹配上面的test2
}
9.3 多个Guards可以通过逗号,标示分割,如果其中任意一个值为true,则匹配成功
demo
.test3(@a,@b) when(@a),(@b){
color:red;
}
.demo19{
.test3(20,true);//第二个Guards是true,匹配test3
}
对应的css:
.demo19 {
color: red;
}
9.4 值得注意的是不同的参数之间也可以比较,而参与比较的也可以一个参数都没有:
@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 }
demo:
.max(@a,@b) when(@a>@b){
width:@a;
}
.max(@a,@b) when(@a<@b){
width:@b;
}
.test4(@a) when(@a=mobile){
color:red;
}
.test4(@a) when(@a=pc){
color:blue;
}
.demo20{
.max(100px,200px);
.test4(mobile);
}
.demo21{
.max(300px,100px);
.test4(pc);
}
对应的css:
.demo20 {
width: 200px;
color: red;
}
.demo21 {
width: 300px;
color: blue;
}
如果需要根据值的类型匹配混合,可以使用 is*
函数:
.mixin (@a, @b: 0) when (isnumber(@b)) { ... }
.mixin (@a, @b: black) when (iscolor(@b)) { ... }
几个检查基本类型的函数:
iscolor
isnumber
isstring
iskeyword
isurl
-
.test5(@a) when(isnumber(@a)){ width:@a; } .test5(@a) when(iscolor(@a)){ color:@a; } .test5(@a) when (isstring(@a)){ &:after{ content:@a; } } .text5(@a) when(isurl(@a)){ background:@a; } .text5(@a) when(iskeyword(@a)){ font-size:20px; } .demo22{ .test5(200px);//isnumber是true } .demo23{ .test5(red);//iscolor是true } .demo24{ .test5("after信息");//isstring是true } .demo25{ .test5("images/1.jpg");//isstring是true } .demo26{ .test5(isurl);//所有的都为false }
对应的css:
-
.demo22 { width: 200px; } .demo23 { color: red; } .demo24:after { content: "after信息"; } .demo25:after { content: "images/1.jpg"; }
如果需要检查一个值(数字)使用了哪个单位,可以使用下面三个函数:
ispixel
ispercentage
isem
- demo
-
.text6(@a) when (ispixel(@a)){ color:red; } .text6(@a) when (isem(@a)){ color:blue; } .text6(@a) when (ispercentage(@a)){ color:#fff; } .demo27{ .text6(10px); } .demo28{ .text6(10%); } .demo29{ .text6(10em); }
对应的css:
-
.demo27 { color: red; } .demo28 { color: #fff; } .demo29 { color: blue; }
最后,你可以使用关键词 and
在 guard
中加入额外的条件:
.mixin (@a) when (isnumber(@a)) and (@a > 0) { ... }
或者,使用关键词 not
否定条件:
.mixin (@b) when not (@b > 0) { ... }
最后,你可以使用关键词 and
在 guard
中加入额外的条件:
.mixin (@a) when (isnumber(@a)) and (@a > 0) { ... }
或者,使用关键词 not
否定条件:
.mixin (@b) when not (@b > 0) { ... }
demo:
.test7(@a) when(isnumber(@a))and(@a>100){
width:@a;
}
.test7(@a) when not(@a>0)and(isnumber(@a)){
margin-top:@a;
}
.demo30{
.test7(200px);
}
.demo31{
.test7(-10px);
}
对应的css:
.demo30 {
width: 200px;
}
.demo31 {
margin-top: -10px;
}
10 嵌套Media Queries
demo:
.inner{
@media print{
background-color:#ccc;
@media (max-width:1700px) and(min-width:600px){
color:red;
}
}
}
.demo32{
.inner;
}
对应的css:
@media print {
.demo32 {
background-color: #ccc;
}
}
@media print and (max-width: 1700px) and (min-width: 600px) {
.demo32 {
color: red;
}
}
11 &的高级用法
用在选择器上的&可以翻转嵌套的顺序,并且可以用在多个类名上
demo:
.child,.sibling{
color:red;
.parent &{
color: black;
}
&+&{
color:blue;
}
}
对应的css:
.child,
.sibling {
color: red;
}
.parent .child,
.parent .sibling {
color: black;
}
.child + .child,
.child + .sibling,
.sibling + .child,
.sibling + .sibling {
color: blue;
}
&
也可以用在混合中用于指示嵌套这个混合的父选择器
12 运算
任何数字、颜色或者变量都可以参与运算,运算应该被包裹在括号中。来看一组例子:
@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);
13 函数
LESS 提供了多种函数用于控制颜色变化、处理字符串、算术运算等等。这些函数在函数手册中有详细介绍。
demo:
@base: #f04615;
@width: 0.5;
.class {
width: percentage(0.5); // returns `50%`
color: saturate(@base, 5%);
background-color: spin(lighten(@base, 25%), 8);
}
上面的代码是将 0.5
转换为 50%
,将颜色饱和度增加 5%
,以及颜色亮度降低25%
色相值增加 8
等用法:
14 命名空间
有时候,你可能为了更好组织 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;
}
15 作用域
LESS 中的作用域跟其他编程语言非常类似,首先会从本地查找变量或者混合模块,如果没找到的话会去父级作用域中查找,直到找到为止。
@var: red;
#page {
@var: white;
#header {
color: @var; // white
}
}
#footer {
color: @var; // red
}
局部变量的优先级高于全局变量的优先级
16 注释
有两种:
单行注释//comment 单行注释,在生成的css中注释不会被保留
多行注释/*comment*/ 多行注释,在生成的css中会保留注释,如果要保留注释,建议多使用多行注释
17 @import 导入
在less中,你既可以导入less文件,也可以导入css文件,只有导入的less文件才会被编译,导入的css文件会被保留原样,如果导入一个css文件,后缀名是.cs不能省略:
demo:
@import style.css
编译过程中对导入的css文件只做一次处理:将导入的文件提到最前,就是@charset之后;
被导入的less文件,会被复制到含有到导入语句的文件中,然后一起编译,导入和被导入的文件公用所有的混合、命名空间、变量和所有的其他结构。
另外导入的语句如果是听过media query指定的,那么导入的语句编译之后会被包裹在@Media中
demo:
@import style.less and screen and (max-width:1000px);
@import style1.css
编译之后:
@media screen and(max-width:1000px){
@import style.less
}
@import style1.css
less文件的导入语句,并不强制要求在页面的顶部,可以被导入到规则内部、混合或者其他机构中
在v1.3.0 - v1.3.3中,@import
允许多次导入同一个文件,可以使用@import-once
让同一文件只导入一次。
在v1.4.0中,移除了@import-once
,@import
的行为就是同一文件只导入一次了。这意味着,如果代码是这样的:
@import “file.less”; @import “file.less”;
那么第二个文件将被忽略。
任何不以.css
结尾的文件都被认为是less文件,将被处理。另外,如果文件名没有后缀,LESS会自动在结尾加上.less
。下面两种写法是等价的:
@import "lib.less";
@import "lib";
在v1.4.0中,你可以强制某个文件使用特写的方式来处理,比如:
@import (css) "lib";
将会输出:
@import "lib";
而
@import (less) "lib.css";
会将lib.css
引入,并当作LESS文件处理。如果你指定了某个文件是less但是没有包含后缀名,LESS将不会自动添加后缀。
18 字符串插值
如果定义的变量需要与字符串连在一起,可以使用@{name}
demo:
@direction:left; .demo33{ border-@{direction}:1px solid red; }
对应的css:
.demo33 { border-left: 1px solid red; }
19 避免编译
有时候我们需要输出一些不正确的 CSS 语法或者使用一些 LESS 不认识的专有语法。
要输出这样的值我们可以在字符串前加上一个 ~,例如:
.class { filter: ~"ms:alwaysHasItsOwnSyntax.For.Stuff()"; }
这叫作“避免编译”,输出结果为:
.class { filter: ms:alwaysHasItsOwnSyntax.For.Stuff(); }
在避免编译的值中间也可以像字符串一样插入变量:
.class { @what: "Stuff"; filter: ~"ms:alwaysHasItsOwnSyntax.For.@{what}()"; }
20 选择器插值
如果需要在选择器中使用less变量,只需要使用与字符串插件一样的@{selector}就可以了,例如:
@name:div1; .@{name}{ border:1px solid red; width:200px; height:200px; }
对应的css:
.div1{ border:1px solid red; width:200px; height:200px; }
注意:(~"@{name}")
语句可以在 LESS 1.3.1 等之前版本中使用,但 1.4.0 版将不再支持这种用法。
21 media query 作为变量
如果需要在media query中使用less变量,可以使用普通的变量方式:
demo:
@choice:~"(max-width:2000px)";
@media screen and @choice{
body{
color:red;
}
}
对应的css:
@media screen and (max-width:2000px) {
body {
color: red;
}
}
变量必须包含完整的media query。这样写会导致报错:@media screen and @partial {
。
在1.4.0中,在开启严格运算模式的情况下,你也可以在media query的条件中插入变量。如@media screen, (max-width: @width) {
。
22 JavaScript求值
在LESS中还可以使用JavaScript表达式来求值。我们不建议谨慎使用这个特性,因为它会使得LESS在其它平台的可编译性变低,也会使得LESS更难维护。如果可能,试着想想能否用一个函数来完成相同的事情,在github上这样的库很多。我们有计划开放对函数的扩展。但,如果你仍然想用的话,你可以通过反引号的方式使用:
@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%);
部分信息摘自:http://www.1024i.com/demo/less/document.html