這些 SCSS 使用技巧真好用

隨著css工程化的普及尝哆,sass在前端工程中越來越舉足輕重淑蔚。當然sass并不局限于管理css全局變量、mixin之類的"臟活累活"蒋搜。

這篇文章會跟隨工程化前端一步一步記錄sass中那些不為人知抒倚,但是又非常使用的小技巧分享給大家褐着。

建議大家收藏隨時觀看。

內(nèi)置函數(shù)

sass官網(wǎng)提供了很多實用的內(nèi)置函數(shù)托呕,當然目前我也是在一步一步探索這些函數(shù)含蓉。目前我會將常用到的內(nèi)置函數(shù)以及場景分享給大家使用洋访。

darken內(nèi)置函數(shù)

定義
lighten()和darken()兩個函數(shù)都是圍繞顏色的亮度值做調(diào)整的,其中l(wèi)ighten()函數(shù)會讓顏色變得更亮谴餐,與之相反的darken()函數(shù)會讓顏色變得更暗姻政。這個亮度值可以是0~1之間。

lighten(#fff,10%) //原色的亮度值 增加百分之10亮度
draken(#fff,10%) // 在原色的基礎上 減少百分之10亮度
應用場景
lighten和darken這兩個內(nèi)置函數(shù)經(jīng)常被用到元素被hover/focus時岂嗓,當我們hover汁展,一個元素的時候。此時并不希望改變這個元素的色值厌殉,但是又想要用戶感知到鼠標停留在這個元素上食绿。此時這兩個內(nèi)置函數(shù)就發(fā)揮了他們的作用了。

@mixin button-type(
  $background,
  $border,
  $color,
  $hover-background: lighten($background, 7.5),
  $hover-border: lighten($border, 10%),
  $hover-color: $color
) {
  color: $color;
  background: $background;
  border-color: $border;
  &:hover {
    color: $hover-color;
    background: $hover-background;
    border-color: $hover-border;
  }
  &:focus,
  &.is-focus {
    color: $hover-color;
    background: $hover-background;
    border-color: $hover-border;
  }
  &[disabled],
  &.is-disabled {
    color: $color;
    background: $background;
    border-color: $border;
  }
}
desaturate

飽和度(Saturation)是指色彩的純度公罕,飽和度越高色彩越純越濃器紧,飽和度越低則色彩變灰變淡。

sass中的desaturate函數(shù)就是針對飽和度操作的內(nèi)置方法楼眷。

desaturate(color,amount) //=> color
使color飽和度降低, 在amount必須之間的數(shù)字0%和100%(包含)铲汪。

@warn
When writing mixins[1] and functions[2], you may want to discourage users from passing certain arguments or certain values. They may be passing legacy arguments that are now deprecated, or they may be calling your API in a way that’s not quite optimal.

編寫MixIn和函數(shù)時,您可能希望勸阻用戶傳遞某些參數(shù)或某些值罐柳。他們可能正在傳遞現(xiàn)在已棄用的傳統(tǒng)參數(shù)掌腰,或者他們可能會以不太最佳的方式調(diào)用您的API。

簡單來說在mixin或者function內(nèi)部张吉,我們可以通過@warn操作符給用戶提示一些警告內(nèi)容輸出在控制臺齿梁。

@mixin prefix($property, $value, $prefixes) {
  @each $prefix in $prefixes {
    @if not index($known-prefixes, $prefix) {
      @warn "Unknown prefix #{$prefix}.";
    }

    -#{$prefix}-#{$property}: $value;
  }
  #{$property}: $value;
}

控制臺會提示

Warning: Unknown prefix wekbit.
    example.scss 6:7   prefix()
    example.scss 16:3  root stylesheet
Inspect()斷電函數(shù)

其實Inspect()函數(shù)用的比較少,主要是用來做校驗類型的肮蛹。

Inspect(...)表達式中的內(nèi)容如果是正常會返回對應的內(nèi)容勺择,如果發(fā)生錯誤則會彈出一個錯誤提示。

Map相關內(nèi)容

Map-has-key
If keys is empty, returns whethermap contains a value associated with $key.

$font-weights: ("regular": 400, "medium": 500, "bold": 700);

 map.has-key($font-weights, "regular"); // true
 map.has-key($font-weights, "bolder"); // false

map.has-key()在scss中的條件判斷時應用場景特別多伦忠。

比如下方這段代碼

$--sm: 768px !default;
$--md: 992px !default;
$--lg: 1200px !default;
$--xl: 1920px !default;

$--breakpoints: (
  'xs' : (max-width: $--sm - 1),
  'sm' : (min-width: $--sm),
  'md' : (min-width: $--md),
  'lg' : (min-width: $--lg),
  'xl' : (min-width: $--xl)
);

@mixin res($key, $map: $--breakpoints) {
  // 循環(huán)斷點Map省核,如果存在則返回
  @if map.has-key($map, $key) {
    @media only screen and #{inspect(map-get($map, $key))} {
      @content;
    }
  } @else {
    @warn "Undefeined points: `#{$map}`";
  }
}
map.get(map,k1,k2,...)

簡單來說就是通過key在map中取到對應的value

config: (a: (b: (c: d))); map.get(config, a, b, c); // d

占位符選擇器%作用

定義
Sass 額外提供了一種特殊類型的選擇器:占位符選擇器 (placeholder selector)。與常用的 id 與 class 選擇器寫法相似缓苛,只是 # 或 . 替換成了 %芳撒。

比如:

%heading {
  margin-top: 0; // 1
  margin-bottom: $headings-margin-bottom;
  font-family: $headings-font-family;
  font-style: $headings-font-style;
  font-weight: $headings-font-weight;
  line-height: $headings-line-height;
  color: $headings-color;
}

應用場景
其實使用%在大多數(shù)(所有)場景下邓深,我的理解就是和@mixin是一樣的效果未桥。使用%占位符選擇器的樣式,只能被@extend進行調(diào)用芥备。

需要注意的是冬耿,如果使用占位符選擇器%定義的樣式圣猎,單獨使用的時候(未通過extend)進行調(diào)用掀潮,那么這段樣式是不會編譯到css的輸出結果之后的逮诲。

Partials import
定義
和css類似scss支持@import命令,但css的import命令每次調(diào)用都會創(chuàng)建一個額外的html請求易茬,但scss的import命令是編譯時將文件包含在css中,不需要額外發(fā)起請求寞忿。

如果我們需要導入 SCSS 或者 Sass 文件交胚,但又不希望將其編譯為 CSS,只需要在文件名前添加下劃線绊起,這樣會告訴 Sass 不要單獨編譯這些文件精拟,但導入語句中卻不需要添加下劃線。

簡單來說虱歪,項目目錄中的所有scss文件在編譯階段都會被編譯成為一個個css文件蜂绎。

但是對于一個公用樣式文件,此時我們并不需要將它編譯成為單獨的css文件笋鄙,而是希望將公用文件中的樣式插入到對應引入樣式文件中师枣,我們只需要在引入它的文件中將它編譯進入引入的css文件中就可以。

此時給文件名稱以_開頭就可以告訴scss在編譯階段并不會將它編譯成為單獨的css文件萧落,而是僅僅會將它的樣式編譯進入引入它的樣式文件中去践美。

比如一個文件夾兩個 scss 文件,一個 root.scss,一個 _vars.scss找岖。

// 第一個 scss 文件夾名 -o 是輸出文件夾名稱npx node-sass scss -o output// 只會有一個文件生成
rendering Complete, saving .css file...
Wrote CSS to /Users/liusha/Public/vikingship/output/root.css //將 _vars 該名稱為 vars.scss 再執(zhí)行一遍
Rendering Complete, saving .css file...
Wrote CSS to /Users/liusha/Public/vikingship/output/root.css
Rendering Complete, saving .css file...
Wrote CSS to /Users/liusha/Public/vikingship/output/vars.css
會有兩個文件生成
應用場景
這在組件庫的開發(fā)中是非常有用的拨脉,定義單獨組件的樣式文件以Partials import進行定義,不單獨打包成為css文件宣增,在最終導入的樣式文件中統(tǒng)一進行合并管理而不打包出單獨的css文件玫膀。

變量聲明global與default

!default 默認變量
可以在變量的結尾添加 !default 給一個未通過 !default 聲明賦值的變量賦值,此時爹脾,如果變量已經(jīng)被賦值帖旨,不會再被重新賦值,但是如果變量還沒有被賦值灵妨,則會被賦予新的值解阅。

比如這樣一段代碼:

$color:red;
$color:blue !default;

.modules-a {
    color: $color; // red
}

我們可以看到即使是先聲明的red,因為blue !default泌霍,所以紅色覆蓋了藍色货抄。!default聲明變量的意思就是說如果項目中存在相同的聲明則優(yōu)先使用別的聲明,如果不存在則使用!default的值朱转,可以理解為默認值蟹地。

!global全局聲明
變量支持塊級作用域,嵌套規(guī)則內(nèi)定義的變量只能在嵌套規(guī)則內(nèi)使用(局部變量)藤为,不在嵌套規(guī)則內(nèi)定義的變量則可在任何地方使用(全局變量)怪与。將局部變量轉換為全局變量可以添加 !global 聲明

在scss中我們都清楚局部變量的定義是無法影響同名的global變量的。但是我們可以通過!global在局部作用域中去定義一個全局都可以使用的變量缅疟。同樣也可以通過!default在局部作用域中去覆蓋一個全局變量的值分别。

#main {
  $width: 5em !global;
  width: $width;
}

#sidebar {
  // 同樣可以使用$width全局變量
  width: $width;
}
編譯為

#main {
  width: 5em;
}

#sidebar {
  width: 5em;
}

mixin
參數(shù)變量...
有時遍愿,不能確定混合指令需要使用多少個參數(shù),比如一個關于 box-shadow 的混合指令不能確定有多少個 'shadow' 會被用到耘斩。這時沼填,可以使用參數(shù)變量 … 聲明(寫在參數(shù)的最后方)告訴 Sass 將這些參數(shù)視為值列表處理.

其實就類似于js中的...rest運算符。

@mixin box-shadow($shadows...) {
  -moz-box-shadow: $shadows;
  -webkit-box-shadow: $shadows;
  box-shadow: $shadows;
}
.shadows {
  @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}

編譯后:

.shadowed {
  -moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
  -webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
  box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
}

使用括授,分隔為.shadowed元素添加多個陰影倾哺。

@content-- 向混合樣式中導入內(nèi)容
在引用混合樣式mixin的時候,可以先將一段代碼導入到混合指令中刽脖,然后再輸出混合樣式羞海,額外導入的部分將出現(xiàn)在 @content 標志的地方

比如這樣的代碼,我們在include中填充了對應的樣式曲管,在mixin中可以通過@content使用却邓。

@mixin apply-to-ie6-only {
  * html {
    @content;
  }
}
@include apply-to-ie6-only {
  #logo {
    background-image: url(/logo.gif);
  }
}

編譯為

// mixin中接受了include 可以理解為插槽
* html #logo {
  background-image: url(/logo.gif);
}

為便于書寫,@mixin 可以用 = 表示院水,而 @include 可以用 + 表示腊徙,所以上面的例子可以寫成:

// = 簡寫mixin
=apply-to-ie6-only

  • html
    @content

// + 簡寫include
+apply-to-ie6-only

logo

background-image: url(/logo.gif)

注意: 當 @content 在指令中出現(xiàn)過多次或者出現(xiàn)在循環(huán)中時,額外的代碼將被導入到每一個地方檬某。

@at-root
常規(guī)用法
@at-root指令可以使一個或多個規(guī)則被限定輸出在文檔的根層級上撬腾,而不是被嵌套在其父選擇器下。

比如

.parent {
  ...
  @at-root .child { ... }
}

編譯之后.child并不會嵌套在任何規(guī)則之下恢恼,因為使用了@at-root選擇符

.parent { ... }
.child { ... }

@at-root同樣也可以當作一個作用域給多個選擇器去使用:

.parent {
  ...
  @at-root {
    .child1 { ... }
    .child2 { ... }
  }
  .step-child { ... }
}

編譯后:

.parent { ... }
.child1 { ... }
.child2 { ... }
.parent .step-child { ... }

支持參數(shù)
@at-root (without: ...) and @at-root (with: ...)

默認使用@at-root不傳遞任何時民傻,他的作用為跳出選擇器的作用域嵌套,當然可以傳遞參數(shù)去使用场斑。

比如下面的@at-root意為跳出@media的嵌套:

@media print {
  .page {
    width: 8in;
    @at-root (without: media) {
      color: red;
    }
  }
}
@media print {
  .page {
    width: 8in;
  }
}
.page {
  color: red;
}

默認 @at-root 只會跳出選擇器嵌套漓踢,而不能跳出@media或 @support,如果要跳出這兩種漏隐,則需使用 @at-root(without: media)喧半,@at-root(without: support)。這個語法的關鍵詞有

四個:

all(表示所有)
rule(表示常規(guī),默認行為青责。
media(表示 media)
support(表示 support )挺据。
我們默認的 @at-root 其實就是 @at-root( without: rule ):跳出作用域嵌套規(guī)則。

@at-root(without: rule)
rule 關鍵詞只能跳出選擇器嵌套脖隶,不能跳出 @media 和 @support

@at-root(without: media)
可以跳出 @media 扁耐,但是沒有跳出父級選擇器

@at-root(without: support)
@at-root(without: support) 和 @at-root(without: media) 相似,只是跳出的是 @support浩村。

@at-root(without: all)
@at-root(without: all) 是跳出所的指令和規(guī)則做葵,如上面的代碼里 @at-root(without: media rule) 我們可以換成 @at-root(without: all),效果是一樣的心墅。

@each in
maps數(shù)據(jù)格式
首先我們來說說在scss中定義類似js中的對象酿矢。

$map: (key1: value1, key2: value2, key3: value3);
我們通過()就可以定義了。比如這樣的Maps結構定義怎燥。

blue: #0d6efd !default;indigo: #6610f2 !default;
purple: #6f42c1 !default;pink: #d63384 !default;
red: #dc3545 !default;orange: #fd7e14 !default;
yellow: #fadb14 !default;green: #52c41a !default;
teal: #20c997 !default;cyan: #17a2b8 !default;

primary:blue !default;
secondary:gray-600 !default;
success:green !default;
info:cyan !default;
warning:yellow !default;
danger:red !default;
light:gray-100 !default;
dark:gray-800 !default;

theme-colors: ( 'primary':primary,
'secondary': secondary, 'success':success,
'info': info, 'warning':warning,
'danger': danger, 'light':light,
'dark': $dark,
);
我們定義了一個maps的主題瘫筐,分別存在對應的名稱和對應的顏色值。

@each in
@each 指令的格式是 var in <list>,var 可以是任何變量名铐姚,比如 length 或者name策肝,而 <list> 是一連串的值,也就是值列表隐绵。

"數(shù)組"迭代
@each 將變量 $var 作用于值列表中的每一個項目之众,然后輸出結果,例如:

@each animal in puma, sea-slug, egret, salamander { .#{animal}-icon {
background-image: url('/images/#{$animal}.png');
}
}
編譯為

.puma-icon {
background-image: url('/images/puma.png'); }
.sea-slug-icon {
background-image: url('/images/sea-slug.png'); }
.egret-icon {
background-image: url('/images/egret.png'); }
.salamander-icon {
background-image: url('/images/salamander.png'); }
此時類似于js中的數(shù)組迭代依许。

對象迭代
當然@each val,key in maps,也支持"迭代"一個對象(maps)棺禾。比如:

@each key,value in theme-colors { .#{prefix}-icon--#{key} { color:value;
}
}
這樣我們就迭代了上邊定義的$theme-colors這個對象,并且取得了他的key,value峭跳。

多個值迭代

The @each directive can also use multiple variables, as in @each v a r 1 , var1, var1,var2, ... in . If is a list of lists, each element of the sub-lists is assigned to the respective variable. For example:

@each 指令也可以使用多個變量膘婶,如@each var1,var2, ... in 。如果是列表列表蛀醉,則子列表的每個元素都分配給相應的變量悬襟。例如

@each $animal, $color, $cursor in (puma, black, default),
                                  (sea-slug, blue, pointer),
                                  (egret, white, move) {
  .#{$animal}-icon {
    background-image: url('/images/#{$animal}.png');
    border: 2px solid $color;
    cursor: $cursor;
  }
}

is compiled to:

.puma-icon {
  background-image: url('/images/puma.png');
  border: 2px solid black;
  cursor: default;
 }
.sea-slug-icon {
  background-image: url('/images/sea-slug.png');
  border: 2px solid blue;
  cursor: pointer; 
}
.egret-icon {
  background-image: url('/images/egret.png');
  border: 2px solid white;
  cursor: move;
 }

css :scope選擇器
偶然在寫jest中看到別人使用xxx.querySelect(':scope')。感到比較新奇隨機查閱記錄一番拯刁。

在JavaScript中脊岳,當用于Element.querySelector[3],Element.querySelectorAll[4]或Element.closest[5]時垛玻,:scope是指調(diào)用這些方法的元素逸绎。例如,document.body.querySelector(":scope")返回body元素夭谤。盡管CSS對 :scope的支持已被移除棺牧,但 :scope 的這種用法仍然被支持

使用:scope選擇器可以匹配對應的方法比如element.querySelector(':scope')則會返回element元素本身。

需要主要的是:scope偽類在css中已經(jīng)不被大多數(shù)瀏覽器支持朗儒,甚至已經(jīng)廢棄颊乘。但是在js這些方法中仍然被主流瀏覽器支持。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末醉锄,一起剝皮案震驚了整個濱河市乏悄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌恳不,老刑警劉巖檩小,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異烟勋,居然都是意外死亡规求,警方通過查閱死者的電腦和手機筐付,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阻肿,“玉大人瓦戚,你說我怎么就攤上這事〈运” “怎么了较解?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赴邻。 經(jīng)常有香客問我印衔,道長,這世上最難降的妖魔是什么姥敛? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任奸焙,我火速辦了婚禮,結果婚禮上徒溪,老公的妹妹穿的比我還像新娘忿偷。我一直安慰自己,他們只是感情好臊泌,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布鲤桥。 她就那樣靜靜地躺著,像睡著了一般渠概。 火紅的嫁衣襯著肌膚如雪茶凳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天播揪,我揣著相機與錄音贮喧,去河邊找鬼。 笑死猪狈,一個胖子當著我的面吹牛箱沦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播雇庙,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谓形,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了疆前?” 一聲冷哼從身側響起寒跳,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎竹椒,沒想到半個月后童太,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年书释,在試婚紗的時候發(fā)現(xiàn)自己被綠了翘贮。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡征冷,死狀恐怖择膝,靈堂內(nèi)的尸體忽然破棺而出誓琼,到底是詐尸還是另有隱情检激,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布腹侣,位于F島的核電站叔收,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏傲隶。R本人自食惡果不足惜饺律,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望跺株。 院中可真熱鬧复濒,春花似錦、人聲如沸乒省。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽袖扛。三九已至砸泛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蛆封,已是汗流浹背唇礁。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惨篱,地道東北人盏筐。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像砸讳,于是被迫代替她去往敵國和親琢融。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容