淺析Scss基礎語法和匯入SASS檔案的方法

2021-10-28 13:00:46
本篇文章主要介紹最基礎的使用和語法,可以看到,Scss引入的變數和巢狀,極大地方便了開發工作,結合其自帶的插值表示式,使得css樣式編寫非常靈活!

Sass語法介紹

sass有兩種語法格式Sass(早期的縮排格式:Indented Sass)和SCSS(Sassy CSS)

目前最常用的是SCSS,任何css檔案將字尾改為scss,都可以直接使用Sassy CSS語法編寫。

所有有效的 CSS 也同樣都是有效的 SCSS。

使用變數

sass使用$符號來標識變數。

變數的作用就是,讓你在整個樣式表中儲存並重用一些資訊或資料。

比如儲存顏色(color)、字型集,或任何你想重用的CSS值。

1. 變數宣告

和css屬性的宣告(property declaration)很像!

如,宣告值為 #F90 的變數 $highlight-color,字型集變數:

$highlight-color: #F90;
$font-stack: Helvetica, sans-serif;
 
body {
    font: 100% $font-stack;
    color: $highlight-color;
}

輸出結果為:

body {
    font: 100% Helvetica, sans-serif;
    color: #F90;
}

變數有作用域,當變數定義在css規則塊內,則該變數只能在此規則塊內使用。

2. 變數參照

凡是css屬性的標準值(比如說1px或者bold)可存在的地方,就可以使用變數。

css生成時,變數會被它們的值所替代。

$color:#A34554;

.box {
  width: 300px;
  height: 400px;
  &-left{
    width: 30%;
    color: $color;
  }
}

生成css為:

.box {
    width: 300px;
    height: 400px;
}
.box-left{
    width: 30%;
    color: #A34554;
}

宣告變數時,變數的值也可以參照其他變數,如下 $highlight-border 變數中使用了 $highlight-color 變數:

$highlight-color: #F90;
$highlight-border: 1px solid $highlight-color;
.selected {
  border: $highlight-border;
}

//編譯後

.selected {
  border: 1px solid #F90;
}

3. 變數名中的中橫線(hyphen)和下劃線(underscore)

sass的變數名可以使用中劃線和下劃線,用中劃線宣告的變數可以使用下劃線的方式參照,反之亦然。

也就是,變數名中的中橫線和下劃線沒有區別,兩者互通。

比如下面的範例,中橫線的$link-color,可以通過下劃線的$link_color參照。

$link-color: blue;
a {
  color: $link_color;
}

//編譯後

a {
  color: blue;
}

相對,使用中橫線更普遍些!

巢狀(Nesting

css中重複寫選擇器是非常惱人的。尤其是巢狀的html元素樣式,如:

#content article h1 { color: #333 }
#content article p { margin-bottom: 1.4em }
#content aside { background-color: #EEE }

Scss的巢狀

Sass中,藉助在規則塊中巢狀子規則塊,可以使重複選擇器只寫一遍,避免重複而且可讀性更高。

比如上面的範例,藉助scss巢狀:

#content {
  article {
    h1 { color: #333 }
    p { margin-bottom: 1.4em }
  }
  aside { background-color: #EEE }
}

scss巢狀開啟(解析)的規則是:從外層到內層,將巢狀規則塊開啟,父級的選擇器放在子級選擇的前面組成一個新的選擇器,然後再回圈開啟內部的巢狀塊處理。

父選擇器的識別符號&

通常,sass解析巢狀時,把父選擇器(#content)通過一個空格連線到子選擇器的前邊(articleaside)形成(#content article#content aside),即生成後代選擇器。

但是對於偽類:hover、對於多class名等情況,則不應該以"後代選擇器"的方式連線,比如:

article a {
  color: blue;
  :hover { color: red }
}

預設生成的article a :hover會讓article元素內a連結的所有子元素在被hover時都會變成紅色,顯然是不正確的(應該應用到a自身)。

為此sass提供了一種特殊的選擇器:父選擇器&。它可以更好的控制巢狀規則!

只要是選擇器可以放置的地方,就都可以在巢狀中同樣使用&

article a {
  color: blue;
  &:hover { color: red }
}

展開時,&被父選擇器直接替換:

article a { color: blue }
article a:hover { color: red }

通過&可以在巢狀塊內,實現在父選擇器之前新增選擇器(非常靈活)。

如:

#content aside {
  color: red;
  body.ie & { color: green }
}

群組選擇器巢狀

css中,使用,分割的群組選擇器可以同時應用樣式在多個選擇器上,如:

h1, h2 {
  margin: 0;
}

但是,如果想對一個特定的容器元素內的多個元素,使用群組選擇器時,就會有很多重複性工作。

.container h1, .container h2, .container h3 { margin-bottom: .8em }

而,sass的巢狀特性,在解開一個內嵌的群組選擇器時,會把每一個內嵌選擇器正確的結合起來:

.container{
  h1,h2,h3{
    margin-bottom:.8em;
  }
}

sass會組合成 .container h1.container h2.container h3 三者的群組選擇器:.container h1, .container h2, .container h3{ xxx }

同樣,群組選擇器內的巢狀也會以這種方式解析:

nav, aside {
  a {color: blue}
}

// nav a, aside a {color: blue}

子組合選擇器和同層組合選擇器:>、+和~

這三種選擇器必須和其他選擇器配合使用。

/* 子組合選擇器> */
article > section { border: 1px solid #ccc }

/* 相鄰組合選擇器+  選擇 元素後緊跟的指定元素 */
header + p { font-size: 1.1em }

/* 同層全體組合選擇器~,選擇所有跟在article後的同層article元素 */
article ~ article { border-top: 1px dashed #ccc }

在sass中使用時,可以通過巢狀直接生成正確的結果(位於外層選擇器的後面,或內層選擇器的前面均可!),而不需要使用&

article {
  /* 放在 裡層選擇器前邊 */
  ~ article { border-top: 1px dashed #ccc }
  > section { background: #eee }
  /* 放在 外層選擇器後邊 */
  dl > {
    dt { color: #333 }
    dd { color: #555 }
  }
  nav + & { margin-top: 0 }
}

解開後的css為:

article ~ article { border-top: 1px dashed #ccc }
article > footer { background: #eee }
article dl > dt { color: #333 }
article dl > dd { color: #555 }
nav + article { margin-top: 0 }

最後一句,nav + & 使用父選擇器&後,原本預設的巢狀規則不再適用,而是直接應用 & 組合的結果

屬性巢狀

sass中,屬性也可以進行巢狀!

把屬性名從中劃線-的地方斷開,在該屬性後邊新增一個冒號:,緊跟一個{ }塊,把子屬性部分寫在這個{ }塊中。這樣就可以實現屬性的巢狀。

nav {
  border: {
     style: solid;
     width: 1px;
     color: #ccc;
  }
}

編譯生成如下:

nav {
  border-style: solid;
  border-width: 1px;
  border-color: #ccc;
}

結合屬性的縮寫形式,可以實現在巢狀屬性中指明需要額外樣式的特殊子屬性。

nav {
  border: 1px solid #ccc {
    /* 單獨設定的 子屬性 */
     left: 0px;
     right: 0px;
  }
}

/* 生成後 */
nav {
  border: 1px solid #ccc;
  border-left: 0px;
  border-right: 0px;
}

插值(Interpolation

類似 es6 中的插值表示式,Sass也提供了插值計算的方式。

插值幾乎可以用在任何地方,作為一個 SassScript 表示式的嵌入結果。

Sass的插值寫法為:#{$variable_name}

利用插值動態生成選擇器、屬性名和值

可以使用插值獲取變數或函數呼叫到一個選擇器、或屬性值。

比如:

$bWidth:5px;
$style:"blue";

.nav {
    border: #{$bWidth} solid #ccc;
    &.nav-#{$style} {
        color: #{$style};
    }
}


// 編譯為:
.nav {
  border: 5px solid #ccc;
}
.nav.nav-blue {
  color: blue;
}

屬性名使用插值變數

使用插值的一個好處是,可以直接將變數值作為屬性名使用。

如下,通過插值,屬性名直接用變數來替代,這樣就可以動態生成屬性。

不使用插值,直接在屬性的位置使用變數$property,將會被處理為對變數的賦值!

$value:grayscale(50%);
$property:filter;

.nav{
   #{$property}: $value;
}

// 編譯為:
.nav {
   filter: grayscale(50%);
}

在 @mixin 中使用插值

@mixin 混合器將在下一節介紹。

插值在寫mixin時非常有用,比如下面通過傳遞的引數建立選擇器(來自官網):

@mixin define-emoji($name, $glyph) {
  span.emoji-#{$name} {
    font-family: IconFont;
    font-variant: normal;
    font-weight: normal;
    content: $glyph;
  }
}

@include define-emoji("women-holding-hands", " ");

編譯後的CSS為:

@charset "UTF-8";
span.emoji-women-holding-hands {
  font-family: IconFont;
  font-variant: normal;
  font-weight: normal;
  content: " ";
}

css的特殊函數(Special Functions【僅作了解】)

CSS中的許多函數都可以在Sass中正常使用,但也有一些特殊的函數有所不同。

所有的特殊函數,呼叫都返回不帶引號的字串。

url()

url() 函數在CSS中很常見,但是它的引數可以是帶引號或不帶引號的URL。

不帶引號的URL在 Sass 中是無效的,所以需要特殊邏輯進行解析。

如下是url()的範例,如果url()的引數是有效的不帶引號URL,Sass會原樣解析它,並且不帶引號時也可以使用插值表示式;如果不是有效的不帶符號URL,將會解析其中的變數或函數,並轉換為普通的CSS函數呼叫。

$roboto-font-path: "../fonts/roboto";

@font-face {
    // 引號中作為一個正常的函數呼叫解析
    src: url("#{$roboto-font-path}/Roboto-Thin.woff2") format("woff2");

    font-family: "Roboto";
    font-weight: 100;
}

@font-face {
    // 使用數學表示式,解析為普通的函數呼叫
    src: url($roboto-font-path + "/Roboto-Light.woff2") format("woff2");

    font-family: "Roboto";
    font-weight: 300;
}

@font-face {
    // 作為一個插值表示式特殊處理
    src: url(#{$roboto-font-path}/Roboto-Regular.woff2) format("woff2");

    font-family: "Roboto";
    font-weight: 400;
}

calc(), clamp(), element()

算數表示式 calc() 和 Sass 的衝突;element() 的引數可以color。

使用它們時,Sass除了處理插值,其他都會保持原樣解析!

min() 和 max()

Sass早於CSS支援使用 min() 和 max(),為了相容所以需要特殊處理。

如果 min() 和 max() 函數呼叫的是普通CSS,則會被編譯為CSS的 min() 和 max()。

普通CSS(Plain CSS)包含巢狀呼叫 calc(), env(), var(), min(), max() 以及 插值。

但是,只要包含 SassScript 的特性,比如 Sass的變數、函數呼叫,min() 和 max() 就會被作為 Sass 的函數處理。

$padding: 12px;

.post {
  // max()沒有使用插值以外的Sass特性, 所以將會被編譯為 CSS 的 max().
  padding-left: max(#{$padding}, env(safe-area-inset-left));
  padding-right: max(#{$padding}, env(safe-area-inset-right));
}

.sidebar {
  // 應為沒有通過插值使用sass變數,此處會呼叫Sass內建的 max()
  padding-left: max($padding, 20px);
  padding-right: max($padding, 20px);
}

註釋

sass另外提供了一種不同於css標準註釋格式/* ... */的註釋語法,即靜默註釋,以//開頭,直到行末結束。

在生成的css中,靜默註釋將會被抹除,這樣,可以按需抹除一些註釋,而不需要全部顯示給其他人。

body {
  color: #333; // 這種註釋內容不會出現在生成的css檔案中
  padding: 0; /* 這種註釋內容會出現在生成的css檔案中 */
}

當標準註釋 /* ... */ 出現在原生css不允許的地方時,也會在編譯後的css中被抹去。

多行註釋 /* ... */ 在 compressed 模式下會被移除,但是如果以 /*! 開頭,則仍會包含在生成的 CSS 中。

匯入SASS檔案

使用@import可以匯入另外的sass檔案(在生成css檔案時會把相關檔案匯入進來)。在被匯入檔案中定義的變數和混合器maxin等均可在匯入檔案中使用。

css中的@import匯入其他css檔案很不常用,因為它是在執行到@import規則時才會載入其他的css檔案,這會導致頁面載入變慢、樣式的錯亂和延遲等問題。

注:Sass官方目前已經開始打算用 @use 替代 @import 規則,因此鼓勵使用 @use。但是,目前只有 Dart Sass 支援 @use,因此,現階段主要還是使用 @import。

scss匯入sidebar.scss檔案,可以使用如下規則:

@import "sidebar";

@import "sidebar.scss";

sass區域性檔案(或分部檔案,partial file

有的sass檔案是專門用於被@import命令匯入的,而不需要單獨生成css檔案,這樣的檔案稱為區域性檔案。

sass的約定是:sass區域性檔案的檔名以下劃線 _ 開頭,sass在編譯時就不會將這個檔案編譯輸出為css。

@import 區域性檔案時,可以省略檔案開頭的下劃線和.scss字尾,不需要寫檔案的全名。

區域性檔案可以被多個不同的檔案引入。對於需要在多個頁面甚至多個專案中使用的樣式,非常有用。

預設變數值

通常情況下,在反覆多次宣告一個變數時,只有最後一個宣告有效(即使用最後一個宣告賦予的值)。

sass通過!default標籤可以實現定義一個預設值(類似css的!important標籤對立),!default表示如果變數被宣告賦值了則用新宣告的值,否則用預設值。

比如一個區域性檔案中:

$fancybox-width: 400px !default;
.fancybox {
  width: $fancybox-width;
}

如果使用者在匯入該sass區域性檔案之前,宣告了一個 $fancybox-width 變數,那麼區域性檔案中對 $fancybox-width 賦值400px的操作就無效。如果使用者沒有做這樣的宣告,則 $fancybox-width 將預設為400px。

也就是,在後面使用 !default 宣告的變數,並不會覆蓋其前面宣告賦值的相同變數值。

巢狀匯入

sass可以在巢狀規則塊的內部使用@import匯入區域性檔案【區域性檔案會被直接插入到css規則內匯入它的地方】。

如區域性檔案_blue-theme.sass內容為:

aside {
  background: blue;
  color: white;
}

將它匯入到一個CSS規則內:

.blue-theme {@import "blue-theme"}

生成的結果跟你直接在 .blue-theme 選擇器內寫 _blue-theme.scss 檔案中的內容完全一樣。

.blue-theme {
  aside {
    background: blue;
    color: #fff;
  }
}

原生的CSS匯入的支援

sass中支援原生css的匯入,會生成原生的scc @import(在瀏覽器解析css時再下載並解析)。

sass中@import生成原生css匯入的條件是:

  • 被匯入檔案的名字以.css結尾;
  • 被匯入檔案的名字是一個URL地址(比如http://www.sass.hk/css/css.css%EF%BC%89
  • 被匯入檔案的名字是CSS的url()值。

如果想將原始的css檔案,當做sass匯入,可以直接修改.css字尾為.scss(sass語法完全相容css)。

更多程式設計相關知識,請存取:!!

以上就是淺析Scss基礎語法和匯入SASS檔案的方法的詳細內容,更多請關注TW511.COM其它相關文章!