Sass 混合指令
1. 前言
混合指令在 Sass 中也是一個(gè)比較常用的指令,在前面我們講解的內(nèi)容中有編寫過混合指令 @mixin ,本節(jié)我們將詳細(xì)講解混合指令 @mixin 的語法包括定義混合指令和引用混合指令等等,混合指令同樣非常好用,我們一起來學(xué)習(xí)它吧。
2. 什么是 Sass 混合指令
混合指令的出現(xiàn)使你可以定義在樣式表中重復(fù)使用的樣式,這可以使你免去編寫過多重復(fù)的樣式,而且在混合指令 @mixin 中你也可以做一些邏輯處理?;旌现噶钍且粋€(gè)很好用的指令,它將幫你更合理的維護(hù)樣式代碼,學(xué)會(huì)這種方式寫起樣式來也很便利,下面我們開始詳細(xì)的講解它。
3. 語法詳情
混合指令的寫法是 @mixin name { … } 或者 @mixin name(<arguments…>) { … },第一種寫法是不傳參的指令,第二種寫法是傳參的指令,我們先來舉個(gè)簡單的例子看下混合指令的樣子:
@mixin border {
border: {
width: 1px;
color: #cccccc;
style: solid;
}
}
上面我寫的這個(gè)混合指令是一個(gè)不需要傳參的,那么它怎么用呢?轉(zhuǎn)換為 CSS 后是什么呢?下面我們從混合指令的定義開始逐一講解。
3.1 定義和引用混合指令
混合指令的定義是在 @mixin 后跟指令名字和 {} ,在 {} 中你可以寫一些樣式,同時(shí)也可以用一些函數(shù)或者前面章節(jié)講的控制指令,現(xiàn)在我們定義一個(gè)不接收參數(shù)的混合指令和一個(gè)接收參數(shù)的混合指令:
// 不接收參數(shù)的混合指令
@mixin border {
border: {
width: 1px;
color: #cccccc;
style: solid;
}
}
// 接收參數(shù)的混合指令
@mixin font($size: 12px, $weight: 100) {
font: {
family: "Myfont";
weight: $weight;
size: $size;
}
}
.box {
// 引用混合指令
@include border;
}
.item {
// 引用混合指令并傳參
@include font(20px, 500);
}
上面的代碼中我們分別定義了兩個(gè)簡單的混合指令,然后在 .box 和 .item 的樣式中通過 @include 引用混合指令,在 @include 后直接跟混合指令的名稱就可以引用了,傳參如上面代碼所示,那么上面這段代碼將會(huì)轉(zhuǎn)換為如下的 CSS 代碼:
.box {
border-width: 1px;
border-color: #cccccc;
border-style: solid;
}
.item {
font-family: "Myfont";
font-weight: 500;
font-size: 20px;
}
看到轉(zhuǎn)換后的 CSS 代碼是不是感覺混合指令很強(qiáng)大,我們把指令寫好后,可以在任何需要它的地方來使用,而且我們只需要傳參就可以生成各種各樣的樣式代碼。還有一點(diǎn)需要注意的是,在 Sass 中,@minxin 后面的名字將連字符和下劃線視為是相同的!
3.2 混合指令的參數(shù)
在上面的代碼中我們已經(jīng)知道了混合指令是可以傳參數(shù)的,參數(shù)是在指令名后面由括號(hào)括起來的變量名列表,混合指令每次調(diào)用都可以操作這些傳入的參數(shù)。
這些參數(shù)只要聲明了就必須傳入,如果你想讓某個(gè)參數(shù)成為可選的,你需要為這個(gè)參數(shù)賦一個(gè)默認(rèn)值,賦默認(rèn)值的方法就像變量聲明賦值一樣,直接在變量名后面加冒號(hào)然后跟默認(rèn)值。我們舉例看下:
// 沒有賦默認(rèn)值的參數(shù)
@mixin font-one($size, $weight) {
font: {
family: "Myfont";
weight: $weight;
size: $size;
}
}
// 賦默認(rèn)值的參數(shù)
@mixin font($size: 12px, $weight: 100) {
font: {
family: "Myfont";
weight: $weight;
size: $size;
}
}
從上面的代碼中可以看出是否賦默認(rèn)值的區(qū)別,默認(rèn)值還可以引用前面的參數(shù)。除了默認(rèn)值,在傳入?yún)?shù)的時(shí)候我們還可以按名稱傳入?yún)?shù),什么意思呢,我們直接舉例看下:
@mixin font($size: 12px, $weight: 100) {
font: {
family: "Myfont";
weight: $weight;
size: $size;
}
}
.item {
// 按名稱傳入?yún)?shù)
@include font-one(20px, $weight: 800);
}
上面這段代碼將會(huì)轉(zhuǎn)換為如下的 CSS 代碼:
.item {
font-family: "Myfont";
font-weight: 800;
font-size: 20px;
}
按名稱傳入?yún)?shù)使我們可以更好的控制混合指令接收的參數(shù),但這個(gè)方法還是盡量少用,因?yàn)閰?shù)名有時(shí)在多人開發(fā)的時(shí)候可能不是一成不變的!
有時(shí)候 @mixin 接收的參數(shù)個(gè)數(shù)你可能不不清楚有多少個(gè),那么你可以將最后一個(gè)參數(shù)以 … 結(jié)尾,那么所有額外的參數(shù)都將傳給該參數(shù),然后在 @mixin 里來獲取所有參數(shù),我們舉個(gè)例子直觀的感受下:
@mixin fonts($s, $familys...) {
font:{
size: $s;
family: $familys;
}
}
.p {
@include fonts(12px, "one", "two", "three")
}
上面這段代碼轉(zhuǎn)換為 CSS 代碼如下:
.p {
font-size: 12px;
font-family: "one", "two", "three";
}
除此之外,@mixin 還可以通過參數(shù)列表接收任意參數(shù),然后通過 meta.keywords() 這個(gè)函數(shù)來使用傳入的這些參數(shù),我們下面舉例看下:
@mixin args($args...) {
@each $key, $val in keywords($args) {
font: $key $val;
}
}
.p {
@include args($one: 1, $two: 2, $three: 3)
}
上面這個(gè)例子是為了讓你更直觀的看到這種傳參方式,實(shí)際樣式中不會(huì)這么寫,上面這段代碼我們通過循環(huán) keywords() 函數(shù)返回的值來使用傳入的參數(shù),它將會(huì)被轉(zhuǎn)化成如下的 CSS 代碼:
.p {
font: one 1;
font: two 2;
font: three 3;
}
混合指令在傳參這塊還是有挺多方式的,你可以根據(jù)實(shí)際的需求來自行選擇上面的傳參方式,這使得我們用起它來很靈活。
3.3 導(dǎo)入內(nèi)容到混合指令
@mixin 指令除了可以接收參數(shù)外,還可以接收樣式塊,我們也稱之為內(nèi)容塊。在 @mixin 中可以使用 @content 來聲明接收的內(nèi)容塊,內(nèi)容塊是通過 {} 的方式傳入的,然后會(huì)注入到 @content 所在的位置。我們舉例來看下:
@mixin hover {
&:hover {
@content;
}
}
.button {
border: 1px solid black;
@include hover {
border-width: 2px;
}
}
從上面的代碼我們可以看到在 @mixin 的 :hover 中我們使用 @content 來接收內(nèi)容塊,然后在使用這個(gè) @mixin 的時(shí)候直接跟一個(gè)以 {} 包裹的內(nèi)容塊,就會(huì)到 @content 的位置,轉(zhuǎn)換為 CSS 代碼如下:
.button {
border: 1px solid black;
}
.button:hover {
border-width: 2px;
}
這種使用方式一般不是很常用,所以你只需要了解下就好。
4. 實(shí)戰(zhàn)經(jīng)驗(yàn)
我們的項(xiàng)目是一個(gè) Vue 單頁應(yīng)用,在我們的實(shí)際項(xiàng)目中有專門的 mixin.scss 文件來管理全局的 @mixin 指令,這里我從中截取出一部分來展示下:
@mixin border ($width: 1px, $color: #cccccc, $style: solid) {
border: {
width: $width;
color: $color;
style: $style;
}
}
@mixin font($size: 12px, $weight: 100, $familys...) {
$family: "Times";
@if length($familys) > 0 {
$family: $familys;
}
font: {
size:$size;
weight: $weight;
family: $family;
}
}
@mixin btn($type: "main") {
border-radius: 4px;
@if $type == "small" {
width: 60px;
height: 20px;
background-color: #e5e5e5;
color: #ffffff;
&:hover {
background-color: #4AA1FF;
}
} @else if $type == "disable" {
width: 80px;
height: 30px;
background-color: #CCCCCC;
color: #ffffff;
} @else {
width: 80px;
height: 30px;
background-color: #e5e5e5;
color: #ffffff;
&:hover {
background-color: #4AA1FF;
}
}
}
從上面的代碼可以看出,我定義的全局的 @mixin 有關(guān)于 border 樣式的,有關(guān)于 font 樣式的,還有一個(gè)我們自己封裝的 button 樣式,這樣在項(xiàng)目的任何需要寫這些樣式的地方直接應(yīng)用這些指令就可以了,而不需要編寫大量的 CSS 樣式,下面我截取一部分在某些頁面中使用這些指令的代碼:
// 使用 border 混合指令
.normal-border {
@include border;
}
.error-border {
@include border(2px, red, solid);
}
// 使用 font 混合指令
.main {
@include font(24px);
.item {
@include font(16px, 600, "serif", "Roman", "Times");
}
}
// 使用 button 混合指令
.btn {
&-main {
@include btn();
}
&-disable{
@include btn("disable");
}
&-small{
@include btn("small");
}
}
上面的代碼轉(zhuǎn)換為 CSS 會(huì)非常的長,這里我就不貼出轉(zhuǎn)換后的 CSS 代碼了。
你可以仔細(xì)看下這些代碼,看看是怎么封裝和使用的,在公司的實(shí)際項(xiàng)目中,如果使用了 Sass ,你一定會(huì)看到類似的這些封裝,當(dāng)然你可能也會(huì)自己封裝這些;你可以對(duì)照這上面兩段定義混合指令和使用混合指令的代碼來復(fù)習(xí)本節(jié)的內(nèi)容,然后自己嘗試這將它轉(zhuǎn)換為 CSS 以便更好的理解!
5. 小結(jié)
本節(jié)內(nèi)容我們講了 Sass 混合指令,這也是一個(gè)好用且常用的指令。你要牢牢記住如何定義混合指令,如何引用混合指令以及如何處理混合指令的參數(shù)!我們用一張圖來演示下:
一般開始頻繁使用指令的時(shí)候就說明你已經(jīng)開始進(jìn)入 Sass 的進(jìn)階水平了,你可以用混合指令為自己或者為其他人封裝一些通用的樣式,不但可以讓自己開發(fā)樣式高效,還可以減少其他人的工作量,所以學(xué)會(huì) Sass 指令很重要!