在大約一年半年前使用Sass的時候,有一件事讓我花了很長的時間,那就是如何區別Sass的@mixin和%placeholder。實際上,%placeholder。在當時的情況這之下,就算是概念對我來說都是黑色地帶。
如果你也碰到類似的情況,不用擔心,因為我會盡量的引導你。今天我們就來探究,什麼時候是@include定義好的@mixin,什麼時候是@extend定義好的%placeholder。你就會明白它們服務的目的是不一樣的,不能混為一談。
注:雖然我們今天討論的是Sass,但這篇文章也適合於其他的CSS預處理器語言。無論是Stylus、LESS,還是你正在使用的Sass。該技術通常做的是同樣的事情,這篇文章介紹的內容都適合你選擇的工具。
接下來我們要做的就是討論,何時使用Sass的@mixin和%placeholder。
Mixin至上
@mixin是一個指令,他可以根據參數個數定義多個規則。可以把它看成是CSS的內容存儲起來,而不是返回的函數的值。 Sass的官方是這樣定義的@mixin:
Mixins allow you to define styles that can be re-used throughout the stylesheet without needing to resort to non-semantic classes like .float-left. Mixins can also contain full CSS rules, and anything else allowed elsewhere in a Sass document. They can even take arguments which allows you to produce a wide variety of styles with very few mixins.
@mixin可以定義樣式,不需要藉用任何類名,比如說.float-left用於整個樣式表中。 @mixin也可以定義所有CSS規則,用於Sass文檔的任何地方。甚至還可以給@mixin定義參數,用極少的@mixin生產更多的樣式。
我們已經介紹了他的術語。我可以說,你會經常發現在你的樣式文件中常常會有一些相同的樣式重複多次出現。你也知道,代碼重複不是好事,你熟悉DRY(不想重複)的概念。要想修正這一點,你只需要給這些重複的樣式聲明定義一個Mixin。
@mixin center() {
display: block;
margin-left: auto;
margin-right: auto;
}
.container {
@include center();
/* 其他的樣式... */
}
/* 其他的樣式... */
.image-cover {
@include center;
}
注:如果沒有給@mixin傳遞任何參數,你可以省略後面的()。甚至你在定義@mixin的時候就可以忽略它。
有了這個@mixin center之後,你每次讓一個元素居中時,就不需要重複的去寫那三行代碼,你只需要使用@include將定義的@mixin center引入進去。這樣是不是很方便呀!
有時候你會想創建一個@mixin,用來速記一些成對的屬性。例如width和height。你一遍又一遍輸入這兩個屬性,難道不累嗎?特別是當兩個屬性的值相同的時候。那麼我們來定義一個@mixin來處理這個現象:
@mixin size($width, $height: $width) {
width: $width;
height: $height;
}
非常簡單,不是嗎?注意,我們在定義了兩個參數,而且使用$height參數的值默認情況之下和$width具有相同的值。現在,如果你要給一個元素定義尺寸,你只需要像下面這樣做:
.icon {
@include size(32px);
}
.cover {
@include size(100%, 10em);
}
注:另外一個很優秀的@mixin實例。每次想讓一個static元素重新定位時,我可以避免每次書寫top,right,bottom,left和position屬性。
了解Placeholder
%placeholder非常的怪異,在SCSS編譯的時候,他是自身是不會輸出代碼的。此時你或許會問,那這個有什麼意義呢?其實不然,這種情形只會發生在沒有使用@extend調用你定義的%placeholder。當然這事情一碼是一碼,我們先來看看如何定義一個%placeholder:
%center {
display: block;
margin-left: auto;
margin-right: auto;
}
編者按:像%placeholder一樣,如果@mixin不被@include調用,同樣是不會編譯出代碼的。所以這部分並不能說明他們的不同之處,只是向大家澄清。即使他看起來像一個CSS代碼塊,但只有調用的時候才會編譯出CSS樣式代碼。
基本上,你把它寫成類似一個類名,不同之處是把代表類名的.符號換成了代表placeholder的%符號。此外,他遵循類同樣的命名规则。
現在,如果你想編譯你的SCSS,在此例中,你看不到編譯出來的文件中有這些代碼。正如我所說的:%placholder不會被編譯到CSS樣式文件中。
所以到目前為止,這個%placeholder是沒有任何作用。你也不能使用他,除非你通過@extend調用了。你可以在一個CSS選擇器或者SCSS的%placeholder中通過@extend調用定義好的%placeholder。正如下面所演示的一樣:
.container {
@extend %center;
}
這一來,Sass會在容器.container調用定義好的%center。 (即使你不知道其中的為什麼也並不重要,因為我們這樣做就行了)。正如我所說的,你也可以在CSS的選擇器中(除了SCSS的%placeholder),也可以@extend定義好的CSS類,如下所示:
.table-zebra {
@extend .table;
tr:nth-of-type(even) {
background: rgba(0,0,0,.5);
}
}
這是一個非常常見的@extend用例。在這個示例中,在.table-zebra類中調用了.table類,因為table.table-zebra具有table.table一些相同的樣式,然後在.table-zebra中添加了修飾這個表樣的特殊樣式規則。在開發網站或應用程序的模塊組件時,通過@extend來調用定義好的類選擇器是非常有用的。
使用哪個呢?
現在的問題是,我們應該使用哪個呢?好吧,在我們領域的一切,依靠的是:依賴。依賴於上下文和你最終要怎麼做。
最好的建議是:如果你需要使用變量,最好使用@mixin,否則使用%placeholder。主要有兩個原因:
首先,你不能在一個%placeholder中使用變量。其實可以,但你不能將變量傳遞到%placeholder中,所以你不能像@mixin一樣根據上下文生成特定的CSS。
第二,當不根據上下文傳入變量時,在Sass中使用@mixin,會使用它們變得更為複雜。簡單的說,在Sass中每次重複複製@mixin,那他的輸出,不僅會造成重複的CSS代碼,還會讓你的樣式文件越來越龐大。
重新回到本文中的第一個示例:
@mixin center {
display: block;
margin-left: auto;
margin-right: auto;
}
.container {
@include center;
}
.image-cover {
@include center;
}
上面SCSS代碼編譯出來的CSS代碼如下:
.container {
display: block;
margin-left: auto;
margin-right: auto;
}
.image-cover {
display: block;
margin-left: auto;
margin-right: auto;
}
請注意,重複的CSS出來了。如果只有三行重複,這並沒有什麼危害,但是如果你的@mixin不只三行代碼,或者在你的項目中重複十幾次調用定義的@mixin,那麼重複的代碼有可能就會變成三百行。如果我們使用%placeholder來改造這個示例呢?
%center {
display: block;
margin-left: auto;
margin-right: auto;
}
.container {
@extend %center;
}
.image-cover {
@extend %center;
}
編譯出來的CSS代碼:
.container, .image-cover {
display: block;
margin-left: auto;
margin-right: auto;
}
好多了,編譯出來的代碼,採用群組選擇器將重複的代碼合併在一起。所以當你知道一些樣式永久不變,而且會重複出現多次的時候,你就可以使用@extend擴展一個定義好的%placeholder。這樣可以避免Sass生成重複的代碼,讓你的樣式表更簡潔。
另一方面,如果你願意在相同的樣式基礎上具有不同的樣式(比如size,color),那麼使用@mixin是最好的方法。如果你有一個組件,其中有固定的樣式,也有動態的樣式,那麼@minxin和%placeholder將是最佳選擇。
%center {
margin-left: auto;
margin-right: auto;
display: block;
}
@mixin skin($color, $size) {
@extend %center;
background: $color;
height: $size;
}
a { @include skin(pink, 10em) }
b { @include skin(blue, 90px) }
在這種情況這下,在@mixin中擴展了設置固定樣式的%placeholder,而不是直接在裡面通過@extend來擴展%placeholder,這樣可以讓你的樣式更簡潔:
a, b {
margin-left: auto;
margin-right: auto;
display: block;
}
a {
background: pink;
height: 10em;
}
b {
background: blue;
height: 90px;
}
結論
通過這篇教程,我希望你不僅清楚@mixin和%placeholder,而且還應該知道什麼時候用什麼,他對編譯出來的CSS會有什麼影響。
如果你有關於Sass功能有什麼不同的體驗和經驗,歡迎在評論中與我們一起分享。
本文轉自w3c plus,出處:
英文原文:http://www.sitepoint.com/sass-mixin-placeholder/
中文譯文:http://www.w3cplus.com/preprocessor/sass-mixin-placeholder.html