LESS - Mixins(混入)

混入 Mixins

混入是指把已存在的樣式混入到別的樣式中烈拒。

你可以把 class 選擇器 和 id 選擇器混入到其他樣式中。例如:
.a, #b {
   color: red;
}

.mixin-class {
  .a();
}
.mixin-id {
  #b();
}

輸出結(jié)果:

.a, #b {
  color: red;
}
.mixin-class {
  color: red;
}
.mixin-id {
  color: red;
}

注意:當(dāng)調(diào)用 mixin 時(shí)岁歉,括號(hào)是可選的

// 下面兩種 mixin 的調(diào)用方法效果是一樣的
.a, #b {
  color: red;
}

.mixin-class {
  .a();
}
.mixin-class {
  .a;
}
不把 Mixin 輸出到編譯后的 CSS 中

如果你想用 mixin 但又不想把它輸出到編譯結(jié)果中惶翻,在定義 mixin 的時(shí)候姑蓝,在 mixin 后面加上括號(hào)

.my-mixin {
  color: black;
}
// 注意 my-other-mixin 后面加了括號(hào)
.my-other-mixin() {
  background: white;
}

.class {
  .my-mixin;
  .my-other-mixin;
}

編譯輸出結(jié)果:

.my-mixin {
  color: black;
}
//可以看到這一行并沒(méi)有輸出上面定義的 my-other-mixin. 但是下面的 .class 中卻含有 background: white;
.class {
  color: black;
  background: white;
}
Mixin 中使用選擇器

Mixin 中不只可以寫(xiě) css 樣式屬性,還可以包含選擇器吕粗。例如:

.my-hover-mixin() {
  &:hover {
    border: 1px solid red;
  }
}

button {
  .my-hover-mixin();
}

編譯輸出結(jié)果:

button:hover {
  border: 1px solid red;
}
命名空間

如果要在更復(fù)雜的選擇器中混入屬性纺荧,可以疊加多個(gè)id或類(lèi)。

#outer {
  .inner {
    color: red;
  }
}

.c {
  #outer > .inner;
}

> 和空格都可以省略。如下

// 下面的寫(xiě)法效果是一樣的
#outer > .inner;
#outer > .inner();
#outer .inner;
#outer .inner();
#outer.inner;
#outer.inner();

這種方法的一個(gè)用途被稱(chēng)為命名空間宙暇。您可以將mixin放在id選擇器下输枯,這樣可以確保它不會(huì)與另一個(gè)庫(kù)沖突(即隔離外界干擾,避免其他樣式對(duì)該 mixin 的影響)占贫。例如:

#my-library {
  .my-mixin {
    color: black;
  }
}

// 可以如下方法調(diào)用
.class {
  #my-library > .my-mixin();
}
命名空間守衛(wèi)

如果命名空間具有保護(hù)桃熄,則僅當(dāng)保護(hù)條件返回true時(shí)才使用由其定義的mixin。命名空間保護(hù)的計(jì)算方式與mixin上的保護(hù)完全相同型奥,因此接下來(lái)兩個(gè)mixin的工作方式相同:

#namespace when (@mode=huge) {
  .mixin() {/* */}
}

#namespace {
  .mixin() when (@mode=huge) {/* */}
}

下面的 default 函數(shù)對(duì)于嵌套的 命名空間 和 mixin 有相同的返回值瞳收,因此如下的 mixin 永遠(yuǎn)不會(huì)執(zhí)行。因?yàn)樗哪骋粋€(gè)守衛(wèi)(即 default()not(default()))肯定是false:

#sp_1 when (default()) {
  #sp_2 when (default()) {
    .mixin() when not(default()) {/* */}
  }
}
!important關(guān)鍵字

在 mixin 調(diào)用之后使用 !important 關(guān)鍵字厢汹,會(huì)把 mixin 所包含的全部css屬性標(biāo)記為 !important.

.foo (@bg: #f5f5f5, @color: #900) {
  background: @bg;
  color: @color;
}


.unimportant {
  .foo();
}
.important {
  .foo() !important;
}

輸出結(jié)果為:

.unimportant {
  background: #f5f5f5;
  color: #900;
}
.important {
  background: #f5f5f5 !important;
  color: #900 !important;
}

攜帶參數(shù)的混入

怎么傳遞參數(shù)給 mixins 呢?
Mixins 也可以攜帶參數(shù)螟深,這些參數(shù)是在選擇器調(diào)用 mixin 時(shí)傳遞給它的變量.
例如:

.border-radius(@radius) {
  -webkit-border-radius: @radius;
     -moz-border-radius: @radius;
          border-radius: @radius;
}

下面是我們?nèi)绾握{(diào)用該mixin:

#header {
  .border-radius(4px);
}
.button {
  .border-radius(6px);
}

帶參數(shù)的 mixins 可以為其參數(shù)設(shè)置默認(rèn)值:

.border-radius(@radius: 5px) {
 -webkit-border-radius: @radius;
    -moz-border-radius: @radius;
         border-radius: @radius;
}

這樣我們可以像下面這樣使用:

#header {
  .border-radius;
}

這樣 idheader 的元素會(huì)有5px的邊框圓角。

也可以不給 mixin 傳遞參數(shù)烫葬。當(dāng)你想在編譯后的 CSS 中包含該 mixin 的所有屬性界弧, 卻又想隱藏某些規(guī)則集(ruleset),這會(huì)非常有用搭综。

.wrap() {
  text-wrap: wrap;
  white-space: -moz-pre-wrap;
  white-space: pre-wrap;
  word-wrap: break-word;
}

pre { .wrap }

編譯后的輸出結(jié)果為:

// 定義的 .wrap() 這個(gè) mixin夹纫, 因?yàn)?.wrap 后面加了括號(hào),這個(gè)mixin 并沒(méi)有輸出到css中
pre {
  text-wrap: wrap;
  white-space: -moz-pre-wrap;
  white-space: pre-wrap;
  word-break: break-word;
}
攜帶多個(gè)參數(shù)的 mixin

多個(gè)參數(shù)之間用 逗號(hào)分號(hào) 隔開(kāi)设凹,推薦用 分號(hào). 逗號(hào)有兩重意思,它可以被解釋為 mixin參數(shù)的分隔符 或者是 CSS列表分隔符

使用逗號(hào)作為 mixin 參數(shù)分隔符時(shí),而 mixin 的每一個(gè)參數(shù)又是需要用逗號(hào)分開(kāi)的列表茅姜,這將不可能實(shí)現(xiàn)闪朱。另一方面,如果編譯器在調(diào)用或聲明 mixin 的地方發(fā)現(xiàn)至少一個(gè) 分號(hào) 钻洒,編譯器就會(huì)認(rèn)為所有的參數(shù)將以 分號(hào) 分隔奋姿,所有的逗號(hào)都是css列表:

  • 兩個(gè)參數(shù),每個(gè)參數(shù)是逗號(hào)分隔的列表: .name(1, 2, 3; something, else).
  • 三個(gè)參數(shù)素标,每個(gè)參數(shù)都是一個(gè)數(shù)字: .name(1, 2, 3).
  • 使用偽分號(hào)創(chuàng)建一個(gè)包含逗號(hào)分隔css列表的參數(shù)的mixin調(diào)用: .name(1, 2, 3;).
  • 逗號(hào)分隔默認(rèn)值: .name(@param1: red, blue;).

使用相同的名稱(chēng)和參數(shù)數(shù)量定義多個(gè) mixins 是允許的称诗。LESS 會(huì)使用所有 可以使用的 css屬性。記住如下mixin編譯規(guī)則:
如果以 .mixin(green) 這樣只攜帶一個(gè)參數(shù)的方式使用這多個(gè)相同名稱(chēng)的 mixin头遭,則所有相同名稱(chēng)的 mixins 且參數(shù)列表中只含有該必填參數(shù)寓免,其他參數(shù)都為可選的 mixins 中所包含的全部 css 樣式合并起來(lái),賦予給調(diào)用這個(gè)只傳了一個(gè)必傳參數(shù)的mixin的選擇器

// 定義第 1 個(gè) .mixin 混入函數(shù)
.mixin(@color) { // 這里的 color 參數(shù)在調(diào)用 .mixin 時(shí)是必傳的计维,因?yàn)闆](méi)有給 color 設(shè)置默認(rèn)顏色值
  color-1: @color;
}

// 定義第 2 個(gè) .mixin 混入函數(shù)袜香,它和上一個(gè)混入函數(shù)同名
.mix(@color; @padding: 2) { // 這里的 color 也是必傳的。padding參數(shù)是選填的鲫惶,因?yàn)橛心J(rèn)值
  color-2: @color;
  padding-2: @padding;
}

// 定義第 3 個(gè) .mixin 混入函數(shù)蜈首,它和第1、2個(gè)混入函數(shù)同名
.mixin(@color; @padding; @margin: 2) { // 這里的 color 是必傳的,需要注意的是欢策,padding也是必傳的吆寨,
                                       // 和1、2兩個(gè) mixin 不同的是踩寇,這個(gè) mixin 有2個(gè)必傳參數(shù)啄清,
                                       // margin 參數(shù)可以省略,因?yàn)橛心J(rèn)值
  color-3: @color;
  padding-3: @padding;
  margin: @margin @margin @margin @margin;
}


.some .selector div {
  .mixin(#008000); // 這里只傳入了 color 這一個(gè)必填參數(shù)姑荷。注意看下面編譯的結(jié)果
}

最終編譯輸出的結(jié)果為:

.some .selector div {
  color-1: #008000;
  color-2: #008000;
  padding-2: 2;
}

上面的編譯結(jié)果盒延,是因?yàn)樵谡{(diào)用同名的 mixin 函數(shù) .mixin 時(shí),只傳入了一個(gè)參數(shù) color,我們逐步看一下最終的編譯結(jié)果是怎么出來(lái)的鼠冕。

  1. 在第一個(gè) .mixin 中添寺,參數(shù) @color 是必傳的,根據(jù)上面的mixin編譯規(guī)則,該 mixin 中包含的 css 樣式最終會(huì)編譯進(jìn)調(diào)用它的選擇器中懈费。
  2. 在第二個(gè) .mixin 中计露,參數(shù) @color 是必傳的,@padding 是可省略的憎乙,因此該 mixin 中只有 @color 一個(gè)必傳參數(shù)票罐,根據(jù)mixin編譯規(guī)則,該 mixin 中包含的 css 樣式最終也會(huì)編譯進(jìn)調(diào)用它的選擇器中泞边。
  3. 在第三個(gè) .mixin 中该押,參數(shù) @color @padding 都是必傳的,根據(jù)mixin編譯規(guī)則阵谚,不符合只有 @color 這一個(gè)必傳參數(shù)的原則蚕礼,因此該 mixin 中的所有樣式 都不會(huì) 編譯進(jìn)輸出結(jié)果中。
命名參數(shù)

mixin 不只可以通過(guò)參數(shù)位置來(lái)傳遞實(shí)參梢什,可以通過(guò)參數(shù)名稱(chēng)來(lái)給它傳遞實(shí)參奠蹬。任何的 mixin 形參都可以通過(guò)指定形參名稱(chēng)來(lái)給它傳遞實(shí)參,而不依賴(lài)于定義該 mixin 時(shí)的形參順序:

.mixin(@color: black; @margin: 10px; @padding: 20px) {
  color: @color;
  margin: @margin;
  padding: @padding;
}


.class1 {
  .mixin(@margin: 20px; @color: #33acfe); // 調(diào)用 mixin 時(shí)通過(guò)指定形參名稱(chēng)傳遞實(shí)參值嗡午,并沒(méi)有按照定義 
                                          // mixin 時(shí)的順序 先 color  其次 margin 最后 padding 的
                                          // 順序來(lái)傳值
}
.class2 {
  .mixin(#efca44; @padding: 40px); // 按原有的形參順序傳值時(shí)囤躁,可以不指定形參名
}
@arguments變量

@arguments 在 mixins 中有獨(dú)特的含義,它包含了傳入的所有參數(shù)荔睹,當(dāng)該 mixin 被調(diào)用時(shí)狸演,如果不想單獨(dú)的寫(xiě)每個(gè)參數(shù)時(shí)會(huì)比較有用。

.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);
}

編譯結(jié)果如下:

.big-block {
  -webkit-box-shadow: 2px 5px 1px #000;
     -moz-box-shadow: 2px 5px 1px #000;
          box-shadow: 2px 5px 1px #000;
}
高級(jí)參數(shù) 和 @rest 變量

當(dāng)一個(gè) mixin 攜帶有可變數(shù)量的參數(shù)時(shí)僻他,可以使用 ...
在變量名后面使用該操作符將會(huì)把這些參數(shù)賦給變量

.mixin(...) { // 匹配第 0 - N 個(gè) arguments
.mixin() {    // 匹配第 0 個(gè) arguments
.mixin(@a: 1) { // 匹配第 0 -1 個(gè) arguments
.mixin(@a: 1; ...) { // 匹配 0 - N 個(gè) arguments
.mixin(@a; ...) { // 匹配 1 - N 個(gè) arguments

此外:

.mixin(@a; @rest...) {
  // @rest 綁定到 @a 之后的所有參數(shù)
  // @arguments 綁定到所有參數(shù)
}
模式匹配

有時(shí)候我們想根據(jù)傳入的參數(shù)改變一個(gè) mixin 的行為严沥。讓我們從一個(gè)基礎(chǔ)的例子開(kāi)始:

.mixin(@s; @color) {...}

.class {
  .mixin(@switch; #888);
}

我們想根據(jù) @switch 的不同讓 mixin 表現(xiàn)出不同的結(jié)果。我們可以如下定義 .mixin:

.mixin(dark; @color) {
  color: darken(@color, 10%);
}
.mixin(light; @color) {
  color: lighten(@color, 10%);
}
.mixin(@_; @color) {
  display: block;
}

此時(shí)如果我們編譯下面的樣式:

@switch: light;

.class {
  .mixin(@switch; #888);
}

編譯得到的CSS結(jié)果為:

.class {
  color: #a2a2a2;
  display: block;
}

.mixin 傳入 color 的地方會(huì)變亮中姜。如果 @switch 的值為 dark, 結(jié)果就是一個(gè)比較暗的顏色消玄。我們逐步分析是怎么編譯出來(lái)的:

  • 第一個(gè) mixin 不匹配跟伏,因?yàn)榈谝粋€(gè)參數(shù)為 dark
  • 第二個(gè) mixin 匹配,因?yàn)樗牡谝粋€(gè)參數(shù)為 light
  • 第三個(gè) mixin 匹配翩瓜,因?yàn)樗牡谝粋€(gè)參數(shù)接受任意值
    只有匹配的 mixin 才會(huì)被采用受扳。變量匹配并綁定到任意值。變量以外的任何內(nèi)容都只和等于自身的值匹配兔跌。
    我們也可以匹配參數(shù)個(gè)數(shù)勘高,看下面的例子:
.mixin(@a) {
  color: @a;
}
.mixin(@a; @b) {
  color: fade(@a; @b);
}

如果我們調(diào)用 .mixin 時(shí)只傳入了一個(gè)參數(shù), 我們會(huì)得到第一個(gè) .mixin 的編譯結(jié)果.如果傳入了兩個(gè)參數(shù),就會(huì)得到第二個(gè) .mixin 的編譯結(jié)果坟桅,即 @a 變?yōu)?@b.

作為函數(shù)的 mixins

從 mixins 中返回變量或 mixins
在 mixin 中定義的變量和 mixin 是可見(jiàn)的华望,可以在調(diào)用者的作用域中使用。只有一個(gè)例外仅乓,如果調(diào)用方包含同名變量(包括由另一個(gè) mixin 調(diào)用定義的變量)赖舟,則不復(fù)制變量。只有調(diào)用方本地作用域中存在的變量才受保護(hù)夸楣。從父作用域繼承的變量將被重寫(xiě)(覆蓋)宾抓。
例如:

.mixin() {
  @width: 100%;
  @height: 200px;
}

.caller {
  .mixin();
  width: @width;
  height: @height;
}

編譯結(jié)果為:

.caller {
  width: 100%;
  height: 200px;
}

因此,mixin中定義的變量可以作為其返回值豫喧。這允許我們創(chuàng)建一個(gè)可以像函數(shù)一樣使用的mixin
例如:

.average(@x, @y) {
  @average: ((@x + @y) / 2);
}
div {
  .average(16px, 50px); // 調(diào)用 mixin
  padding: @average;
}

編譯結(jié)果為:

div {
  padding: 33px;
}

在調(diào)用者作用域內(nèi)定義的變量不會(huì)被覆蓋石洗。然而,在調(diào)用者父級(jí)作用域中定義的變量將不被保護(hù)且可以被覆蓋:

.mixin() {
  @size: in-mixin;
  @defineOnlyInMixin: in-mixin;
}

.class {
  margin: @size @defineOnlyInMixin;
  .mixin();
}

@size: globaly-defined-value; // 調(diào)用者父作用域 - 無(wú)保護(hù)

編譯結(jié)果為:

.class {
  margin: in-mixin in-mixin;
 }

最后紧显, mixin 中定義的 mixin 也會(huì)被當(dāng)做返回值

.unlock(@value) { // 父級(jí) mixin
  .doSomething() { // 子級(jí) mixin 
    declaration: @value;
  }
}

讲衫、#namespace {
  .unlock(5);  // unlock 做一些混入
  .doSomething(); // 子級(jí) mixin 被拷貝到這里且可用
}

編譯結(jié)果

#namespace {
  declaration: 5;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市孵班,隨后出現(xiàn)的幾起案子涉兽,更是在濱河造成了極大的恐慌,老刑警劉巖重父,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異忽匈,居然都是意外死亡房午,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)丹允,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)郭厌,“玉大人,你說(shuō)我怎么就攤上這事雕蔽≌勰” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵批狐,是天一觀的道長(zhǎng)扇售。 經(jīng)常有香客問(wèn)我前塔,道長(zhǎng),這世上最難降的妖魔是什么承冰? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任华弓,我火速辦了婚禮,結(jié)果婚禮上困乒,老公的妹妹穿的比我還像新娘寂屏。我一直安慰自己,他們只是感情好娜搂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開(kāi)白布迁霎。 她就那樣靜靜地躺著,像睡著了一般百宇。 火紅的嫁衣襯著肌膚如雪考廉。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,287評(píng)論 1 301
  • 那天恳谎,我揣著相機(jī)與錄音芝此,去河邊找鬼。 笑死因痛,一個(gè)胖子當(dāng)著我的面吹牛婚苹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鸵膏,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼膊升,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了谭企?” 一聲冷哼從身側(cè)響起廓译,我...
    開(kāi)封第一講書(shū)人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎债查,沒(méi)想到半個(gè)月后非区,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盹廷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年征绸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俄占。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡管怠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缸榄,到底是詐尸還是另有隱情渤弛,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布甚带,位于F島的核電站她肯,受9級(jí)特大地震影響佳头,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜辕宏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一畜晰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瑞筐,春花似錦凄鼻、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至膘格,卻和暖如春峭范,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瘪贱。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工纱控, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人菜秦。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓甜害,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親球昨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子尔店,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354