摘要:
前面介紹了less的變量和extend語法,今天在研究下混合屬性(Mixin)。混合可以說是less的另一個特征,你可以將通用屬性定義在一塊,然后使用時直接調用此混合屬性。
混合:
在 LESS 中我們可以定義一些通用的屬性集為一個選擇器,然后在另一個選擇器中去調用這些屬性. 例如:
.a, #b { color: red; } .mixin-class { .a(); } .mixin-id { #b(); }
編譯后
.a, #b { color: red; } .mixin-class { color: red; } .mixin-id { color: red; }
注意:在調用混合時,可以加括號也可以不加括號。下面這個也是對的:
.a, #b { color: red; } .mixin-class { .a; } .mixin-id { #b; }
如果你只想定義一個混合,則可以再選擇器后面加上括號,如下:
.my-mixin { color: black; } .my-other-mixin() { background: white; } .class { .my-mixin; .my-other-mixin; }
編譯后,加括號的.my-other-mixin()不會被編譯。
.my-mixin { color: black; } .class { color: black; background: white; }
任何 CSS class, id 或者 元素 屬性集都可以以同樣的方式引入.通用選擇器中可以嵌套選擇器。
命名空間:
如果你想混合屬性在一個更復雜的選擇器,可以疊放多個id或類。如下:
#outer { .inner { color: red; } }
如果想使用這個混合屬性,你可以這樣,下面四個都是等價的
.c{ #outer > .inner; } .c{ #outer > .inner(); } .c{ #outer.inner; } .c{ #outer.inner(); }
你可以將混合屬性定義在一個id的下面,這樣就避免了與其他混合沖突。
關鍵字!important:
在使用混合屬性后面加上!important關鍵字,則混合中的所有屬性都會加上關鍵字!important。例如:
.foo (@bg: #f5f5f5, @color: #900) { background: @bg; color: @color; } .unimportant { .foo(1); } .important { .foo(2) !important; }
編譯后
.unimportant { background: #f5f5f5; color: #900; } .important { background: #f5f5f5 !important; color: #900 !important; }
帶參數的混合:
混合屬性也可以通過括號傳遞參數,如下:
.border-radius(@radius) { -webkit-border-radius: @radius; -moz-border-radius: @radius; border-radius: @radius; }
我們只需要在使用它的時候傳遞一個參數即可,如下:
#header { .border-radius(4px); } .button { .border-radius(6px); }
當然我們也可以給參數一個默認值,這樣使用的時候可以傳值也可以不傳值。如下:
.border-radius(@radius: 5px) { -webkit-border-radius: @radius; -moz-border-radius: @radius; border-radius: @radius; }
如果我們沒有傳值,則會使用默認值5px。
當然我們也可以傳遞多個參數,如下:
.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); }
編譯后
.some .selector div { color-1: #008000; color-2: #008000; padding-2: 2; }
從編譯的結果可以看出,less也有函數重載的特性。當我們定義相同混合屬性名,參數不同,然后.mixin(#008000);調用,第一和第二混合都能匹配,但是第三個缺少參數@padding的值,所以不會引用第三個混合屬性。
我們不僅可以傳多個值,還可以指定屬性名傳值,如下:
.mixin(@color: black; @margin: 10px; @padding: 20px) { color: @color; margin: @margin; padding: @padding; } .class1 { .mixin(@margin: 20px; @color: #33acfe); } .class2 { .mixin(#efca44; @padding: 40px); }
關鍵字@arguments:
@arguments有特殊的含義,類似於js的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); }
編譯后
.big-block { -webkit-box-shadow: 2px 5px 1px #000; -moz-box-shadow: 2px 5px 1px #000; box-shadow: 2px 5px 1px #000; }
關鍵字@reset:
與@arguments不同的是@reset包含除指明參數之外的參數,例如:
.mixin(@a; @rest...) { // @rest包含了@a之后的參數 // @arguments包含了所有參數 }
模式匹配:
有時候你想讓混合根據你傳入的參數做不同的事情,比如:
.mixin(dark; @color) { color: darken(@color, 10%); } .mixin(light; @color) { color: lighten(@color, 10%); } .mixin(@_; @color) { display: block; } .class { .mixin(@switch; #888); }
對於.class你賦給變量@switch不同的值,不同的混合屬性會被調用,比如
@switch: light;
編譯后
.class { color: #a2a2a2; display: block; }
作為函數使用Mixin:
當我們把混合當做函數使用時,在調用函數之后,函數中的變量是可以使用的,除非調用混合屬性的元素自己定義了同樣的變量。比如:
.mixin() { @width: 100%; @height: 200px; } .caller { .mixin(); width: @width; height: @height; }
編譯后
.caller { width: 100%; height: 200px; }
使用表達式:
.average(@x, @y) { @average: ((@x + @y) / 2); } div { .average(16px, 50px); // "call" the mixin padding: @average; // use its "return" value }
編譯后
div { padding: 33px; }