最近在研究Less,分享一些Less的知识与栗子,参考资料是Less官网,因为基本是全英文,所以看不惯英文的童鞋可以参考这篇文章,希望能有帮助。
LESS变量:
- 变量声明(最基础的应用—用于css样式):
-
- 使用“@”前缀标记变量;
- @link-color: #428bca; // sea blue
- Less变量用于选择器、URL、属性:
-
-
// Variables@my-selector: banner;// Usage.@{my-selector} { //用花括号将变量名括起来font-weight : bold;line-height : 40px ;margin : 0 auto;}
-
- Less变量甚至可以用于变量名:
-
-
@primary: green;@secondary: blue;.section {@color: primary;.element {color : @@color ;}}
-
- 懒加载:
-
- 变量的使用可以在定义之前(不建议)
- 若一个变量定义多次,则以当前作用域最近的一次为准(和css样式作用域类似),若当前作用域不存在该变量,则往上层作用域查找,直到找到该变量或查找至根作用域为止
父选择器:
- &代表父选择器
- 定义伪类样式:
-
-
a {color : blue;& :hover {color: green;}}
-
- 定义重复性的类的样式:
-
-
.button {&-ok {background-image: url("ok.png");}&-cancel {background-image: url("cancel.png");}}
-
Output:.button-ok {background-image: url("ok.png");}.button-cancel {background-image : url( "cancel.png" );}
-
- 组合式&:
-
- & > &
- & &
- &&
- &,&-ish
-
注意 ,如果多层嵌套,则&不仅代表其最近的父选择器,而是代表其所有的祖先选择器。如:.grand {.parent {& > & { color : red; }}}output:.grand .parent > .grand .parent {color: red;}
- 改变选择器顺序(在孙子的位置做老子的事):
-
-
.header {.menu {border-radius: 5px;.no-borderradius & {background-image:url('images/button-background.png');}}}output:.header .menu {border-radius: 5px;}.no-borderradius .header .menu {background-image:url('images/button-background.png');}
-
继承:
-
&:extend();其思想与面向对象中的继承相同,子选择器可以重写父选择器中的样式
- 从本质上讲,extend继承关注的是编译后的css,而非源less。所以在分析less时应采取css的思考方式而非less
-
nav ul {&:extend(.inline); //&代表的父选择器继承了()内的选择器的样式。background: blue;}.inline { color : red; }Output:nav ul {background: blue;}.inline, nav ul { color: red; }
-
也可直接写成: .a :extend ( .b ) {}和 .a { & :extend ( .b ); }一样的效果
- c:extend(.d all) { // 加上all关键字即即成所有".d”, e.g. 包括".x.d" ,".d.x”,”*.d”,”.d:hover”等等}
- .c:extend(.d) { // 不加all关键字则仅继承css输出为".d”的选择器}
-
可继承多个选择器,用“,”分隔开:.e :extend ( .f , .g ) {}
- 继承的写法与伪类相同,但注意:entend()只能写在最后,如:pre:hover:extend(div pre)
-
若采用继承的内部写法:&:extend(),那么其外部的所有选择器都将作为继承者,如:pre:hover, .some-class { &:extend(div pre); }output:pre:hover:extend(div pre), .some-class:extend(div pre) {}
- extend的精确匹配:
-
- :extend(.class)只匹配”.class”选择器,其它选择器如”.a.class”,”.class.a”,”.class > .a”,包括”*.class”等等统统不匹配,不继承;
-
选择器后的伪类顺序也要一致才能匹配,顺序不一致虽然效果相同,但extend无法匹配,如:link :hover :visited { color : blue; } .selector :extend ( link :visited :hover ) {}匹配不到,不继承
- 属性选择器的写法不影响继承的精确匹配,对属性比较宽容
-
extend不能匹配带有变量的选择器,如:@variable: .bucket; @{variable} { // 插值选择器color: blue;}
- extend在@media中的作用域:仅识别匹配并继承当前@media内的选择器,外部、内部或兄弟@media内的全都不匹配
-
为什么有了mixin还需要extend呢?二者的不同之处在于编译完成后的css写法不同,extend产生的css更为简洁,相对而言mixin会产生大量重复,extend更有利于缩减css的大小。如:使用mixin:.my-inline-block() {display: inline-block;font-size: 0; }.thing1 { .my-inline-block; } .thing2 { .my-inline-block; }Output:.thing1 {display: inline-block;font-size: 0;}.thing2 {display: inline-block;font-size: 0;}使用extend:.my-inline-block {display: inline-block;font-size: 0;}.thing1 { & :extend ( .my-inline-block ); }.thing2 { &:extend(.my-inline-block); }output:.my-inline-block, .thing1, .thing2 { display: inline-block; font-size: 0; }另外,extend可以看作是mixin的一种更高级的替代方式,原因是mixin只能被用于简单的选择器,而例如这类情况:有两个html代码块,你想在这两个代码块中使用相同的样式,此时就可以使用extend将他们联系起来。
混合:
- 你可以将类选择器或id选择器(不妨先称为a)直接混合进另一个选择器(b),这样b选择器就会拥有a选择器中所有的属性设置(非常简单粗暴)
-
举个栗子:.a , #b { color : red; }.mixin-class { .a (); }.mixin-id { #b (); }Output:.a, #b { color: red; }.mixin-class { color: red; }.mixin-id { color: red; }其中调用mixin时的小括号“()”可以省略:.a();与.a;一样
-
不输出mixin:从上个例子我们会发现一个问题,我们声明(“声明”一词用在这里并不正确,但我相信是比较能让人容易理解的表述)的用于mixin的选择器a和b在css输出中也被解析出来了。但是实际上大多数情况下我们使用mixin时是不需要他们被解析成css输出出来的,解决方法非常简单,在声明它们的时候加个括号“()”就可以了,举个栗子:.my-mixin { color : black; }.my-other-mixin () { background : white; }.class { .my-mixin ; .my-other-mixin ; }output:.my-mixin { color: black; }.class { color: black; background: white; }
-
mixin不但可以包含属性,还可以包含选择器。举个栗子:.my-hover-mixin() {&:hover { border: 1px solid red; }}button { .my-hover-mixin(); }outputs:button:hover { border: 1px solid red; }
-
命名空间:当mixin选择器定义多了,难免会遇到名字冲突的情况,此时我们可以采用“封装”的思想,将选择器按照一定规则封装进另外的id选择器里,为什么选择id选择器呢,自然是为了确保唯一性了,举个栗子:可以这么“封装”:#my-library {.my-mixin () { color : black; }}// 可以这么使用:.class { #my-library > .my-mixin (); }以下几种写法是完全相同的:#outer > .inner ;#outer > .inner ();#outer .inner ;#outer .inner ();#outer .inner ;#outer .inner ();
-
!important关键字:在mixin的调用后面加上该关键字会使被调用的mixin选择器中的所有属性在此处都变成!important,举个栗子.foo ( @bg : #f5f5f5 , @color : #900 ) {background : @bg ;color : @color ;}.unimportant { .foo (); }.important { .foo () !important; }outputs:.unimportant {background: #f5f5f5;color: #900;}.important {background: #f5f5f5 !important;color: #900 !important;}
-
你可以给mixin加参数(更像是一个编程语言了,真的舒服),还可以加默认值。举个栗子:.border-radius(@radius: 5px) {-webkit-border-radius: @radius;-moz-border-radius: @radius;border-radius: @radius;}#header { .border-radius ( 4px ); }.button { .border-radius ( 6px ); }.box { .border-radius ; } //这里默认参数为5px
- 多个参数的mixin:
-
-
参数可以用逗号或分号分隔开,但是建议用分号,因为逗号在此处会产生双重含义:1、mixin参数分隔符2、css列表分隔符所以如果使用逗号那么就不可能两者兼顾,而使用分号的话编译器就会将分号视为参数分隔符同时将逗号视为css列表分隔符
-
似乎不是很清晰,栗子会告诉你怎么回事:1、 .name(1, 2, 3; something, else): 两个参数,每个参数都包含一个逗号分隔的列表2、 .name(1, 2, 3): 三个参数,每个参数是一个数字3、 .name(1, 2, 3;): 一个参数,这个参数是一个用逗号分隔的css列表4、 .name(@param1: red, blue;): 用逗号分隔的参数默认值
-
less允许定义多个相同名字的mixin,甚至允许它们拥有不同的参数个数,这种情况less会将所有它能用的属性全用上,直接上栗子:.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 .selector div { .mixin(#008000); }outputs:.some .selector div {color-1: #008000;color-2: #008000;padding-2: 2;}
-
-
@arguments变量在mixin被调用时,@arguments变量包含着其所有变量。当我们不需要处理特定变量时很有用,请看栗子:.box-shadow(@x: 0; @y: 0; @blur: 1px; @color: #000) {-webkit-box-shadow: @arguments;-moz-box-shadow: @arguments;box-shadow: @arguments;}.big-block { .box-shadow(2px; 5px); }outputs:.big-block {-webkit-box-shadow : 2px 5px 1px #000 ;-moz-box-shadow : 2px 5px 1px #000 ;box-shadow : 2px 5px 1px #000 ;}
-
高级参数与@rest变量:我们可以用“…“来获取mixin的多个参数。举个栗子:.mixin (...) { // 匹配 0-N 个参数.mixin () { // 匹配 0 个参数.mixin ( @a : 1 ) { // 匹配 0-1 个参数.mixin ( @a : 1 ; ...) { // 匹配 0-N 个参数.mixin ( @a ; ...) { // 匹配 1-N 个参数.mixin(@a; @rest...) {// @rest 绑定@a之后的参数// @arguments 绑定所有的参数}