天天看點

CSS預處理器 Sass/Scss

文章目錄

    • 介紹
      • Sass是什麼
      • Scss是什麼
      • Scss 與 Sass異同
      • 為什麼使用 Sass?
    • Sass 安裝
      • NPM 安裝(推薦使用)
      • Windows 上安裝
      • Mac OS X (Homebrew)安裝
    • Sass 轉化為 CSS
      • 轉化步驟
      • 自動編譯
    • 編譯輸出的CSS格式
        • :nested:嵌套(預設格式)
        • :compact:緊湊
        • :expanded:擴充
        • :compressed:壓縮
    • Sass 文法
      • 注釋
      • 變量`$`
      • 嵌套
        • 1. 選擇器嵌套
        • 2. 父選擇器 `&`
        • 3. 屬性嵌套
      • 插值語句 `#{}`
      • 資料類型
      • 運算
        • 數字運算
        • 顔色值運算
        • 字元串運算
        • 布爾運算
        • 數組運算
      • 混合-Mixins
      • 控制語句
        • @if
        • @for
        • @each
        • @while
      • Partials與@import
        • @import
        • Sass 導入檔案
        • 局部檔案(Partial)
      • 函數
      • Sass 顔色函數
        • Sass 顔色設定
      • @media
      • 繼承(@extend)
      • 警告與錯誤
    • 了解更多

介紹

Sass是什麼

Sass (英文全稱:Syntactically Awesome Stylesheets) 是一個最初由 Hampton Catlin 設計并由 Natalie Weizenbaum 開發的層疊樣式表語言。Sass 是一個 CSS 預處理器,是 CSS 擴充語言,可以幫助我們減少 CSS 重複的代碼,節省開發時間。

Sass 擴充了 CSS3,增加了規則、變量、混入、選擇器、繼承、内置函數等等特性。

Sass 生成良好格式化的 CSS 代碼,易于組織和維護。

Sass 檔案字尾為 . s c s s \color{red}{.scss} .scss。

Scss是什麼

Scss 是 Sass 3 引入新的文法,是Sassy CSS的簡寫,是CSS3文法的超集。說白了Scss就是Sass的更新版,其文法完全相容 CSS3,并且繼承了 Sass 的強大功能。也就是說,任何标準的 CSS3 樣式表都是具有相同語義的有效的 SCSS 檔案。另外,SCSS 還能識别大部分 CSS hacks(一些 CSS 小技巧)和特定于浏覽器的文法。

所有在 CSS 中正常工作的代碼也能在 Scss 中正常工作。也就是說,對于一個 Sass 使用者,隻需要了解 Sass 擴充部分如何工作的,就能完全了解 Scss。大部分擴充,例如變量、parent references 和 指令都是一緻的;唯一不同的是,SCSS 需 要 使 用 分 号 和 花 括 号 而 不 是 換 行 和 縮 進 \color{red}{需要使用分号和花括号而不是換行和縮進} 需要使用分号和花括号而不是換行和縮進。

Scss 與 Sass異同

Sass 和 Scss 其實就是同一種東西,我們平時都稱之為 Sass,兩者之間不同之處主要有以下兩點:

  1. 檔案擴充名不同:Sass 是以

    “.sass”

    字尾為擴充名,而 Scss 是以

    “.scss”

    字尾為擴充名。
  2. 文法書寫方式不同:Sass 是以嚴格的縮進式文法規則來書寫,不帶大括号({})和分号(😉,而 Scss 的文法書寫和我們的CSS 文法書寫方式非常類似。

我們不妨來看看下面兩段代碼,這樣會更加直覺,更容易了解。

Scss代碼

/* 注
   釋*/
// 注
// 釋
@import "base";
$font-stack:    Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}
@mixin alert {
    color: #000000;
}
.alert-warning {
    @include alert;
}
           

Sass代碼

/* 注
   釋
// 注
   釋
@import base
$font-stack:    Helvetica, sans-serif
$primary-color: #333

body
  font: 100% $font-stack
  color: $primary-color
  
=alert 
  color: #000000

.alert-warning 
  +alert

           

編譯為:

/* 這裡隻展示body中的代碼 */
body {
  font: 100% Helvetica, sans-serif;
  color: #333;
}
           

為什麼使用 Sass?

CSS 本身文法不夠強大,導緻重複編寫一些代碼,無法實作複用,而且在代碼也不友善維護。

Sass 引入合理的樣式複用機制,增加了規則、變量、混入、選擇器、繼承、内置函數等等特性。

Sass 安裝

本章節我們主要介紹 Sass 的安裝與使用。

NPM 安裝(推薦使用)

我們可以使用 npm(NPM 使用介紹)來安裝 Sass。

npm install -g sass
           

**注:**國内 npm 建議使用淘寶鏡像來安裝

Windows 上安裝

我們可以使用 Windows 的包管理器 Chocolatey 來安裝:

choco install sass
           

Mac OS X (Homebrew)安裝

Mac OS 可以使用 Homebrew 包管理器來安裝:

brew install sass/sass/sass
           

官網安裝流程:安裝Sass | Sass中文網

Sass 轉化為 CSS

轉化步驟

  1. 首先建立.scss檔案及其存放目錄和css檔案的存放目錄
  2. 然後在.scss檔案中書寫sass代碼
  3. 最後cd到.scss檔案存放目錄,在指令行輸入
    sass sass/test1.scss css/test1.css
               
    sass sass/test1.scss:css/test1.css
               
    **注:**sass/test1.scss為sass代碼存放目錄及檔案名;css/test1.css為css代碼存放目錄及編譯完成後css代碼存放檔案。

逆向操作,css檔案轉換為sass/scss檔案

sass-convert style.css style.sass
sass-convert style.css style.scss
           

自動編譯

每次修改sass代碼都需要重新執行指令,非常的麻煩,是以下面講述一種自動實時編譯的方式。

監視單個 Sass 檔案(每次修改并儲存時自動編譯)

sass --watch input.scss:output.css
           

例:對目前檔案夾下sass/test1.scss監聽,并自動編譯生成css/test1.css

sass --watch sass/test1.scss:css/test1.css 
           

監視整個檔案夾

輸入指令:

sass --watch sass檔案夾名:css檔案夾名  
           

例:

sass --watch sass:css
           

停止監視

在指令行界面按下:Ctrl + C

編譯輸出的CSS格式

編譯輸出的CSS格式一共有四種:

  • nested:嵌套(預設格式)
  • compact:緊湊
  • expanded:擴充
  • compressed:壓縮

執行個體:

// sass
ul{
  font-size: 15px;
  li{
    list-style: none;
    line-height: normal;
  }
}
           

:nested:嵌套(預設格式)

在執行監測(編譯)指令時,可以指定輸出格式為

nested

sass --watch sass:css --style nested
           

輸出css格式:

ul {
  font-size: 15px; }
ul li {
  list-style: none;
  line-height: normal; }
           

:compact:緊湊

緊湊格式占用的空間要小得多,每個CSS選擇符定義隻占用一行。

要将CSS輸出設定為緊湊格式,可以使用如下指令:

sass --watch sass:css --style compact
           

輸出css格式:

ul { font-size: 15px; }
ul li { list-style: none; line-height: normal; }
           

:expanded:擴充

展開格式看起來像開發人員手寫的格式。

要将CSS輸出設定為展開格式,可以使用如下指令:

sass --watch sass:css --style expanded
           

輸出css格式:

ul {
  font-size: 15px;
}
ul li {
  list-style: none;
  line-height: normal;
}
           

:compressed:壓縮

壓縮格式占用盡可能少的空間,選擇符定義不換行,檔案最小,一般用于生産版本。

要将CSS輸出設定為壓縮格式,可以使用如下指令:

sass --watch sass:css --style compressed
           

輸出css格式:

Sass 文法

注釋

scss檔案中

/* 多行注釋 
*  會包含在沒有壓縮之後的css裡面*/
// 單行注釋(不會出現在css裡面)
           

編譯為:

@charset "UTF-8";
/* 多行注釋 
*  會包含在沒有壓縮之後的css裡面*/
           

**注:**如果編譯輸出的CSS格式是

compressed:壓縮

時,多行注釋也不會再css檔案中出現。

如果想要編譯輸出的CSS格式是

compressed:壓縮

時,多行注釋仍然在css檔案中出現。

scss檔案

/* 多行注釋 */
/*! 強制輸出的注釋内容
*/
ul{
  font-size: 15px;
  li{
    list-style: none;
    line-height: normal;
  }
}
           

編譯後的css檔案

/*! 強制輸出的注釋内容
*/ul{font-size:15px}ul li{list-style:none;line-height:normal}
           

變量

$

變量以美元符号開頭,指派方法與 CSS 屬性的寫法一樣:

$color:#000000; // 變量聲明
$highlight-color: #F90;
$highlight-border: 1px solid $highlight-color; // 将變量直接指派給border屬性
div{ // 變量引用
    color:$color;
    border: $highlight-border;
}
           

編譯為:

/* css */
div {
    color: #000000;
    border: 1px solid #F90;
}
           

将局部變量轉換為全局變量可以添加

!global

聲明:

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

編譯為:

/* css */
#main {
  width: 5em;
}
#sidebar {
  width: 5em;
}
           

嵌套

Sass支援選擇器及屬性嵌套,可以避免代碼的重複書寫。

1. 選擇器嵌套

div {
    h1 {
        color: #333;
    }
    p {
        margin-bottom: 1.4px;
        a {
            color: #999;
        }
    }
}
           

編譯為:

/* css */
div h1 { color: #333; }
div p { margin-bottom: 1.4px; }
div p a { color: #999; }
           

2. 父選擇器

&

在嵌套 CSS 規則時,有時也需要直接使用嵌套外層的父選擇器,例如,當給某個元素設定

hover

樣式時,或者當

body

元素有某個 classname 時,可以用

&

代表嵌套規則外層的父選擇器。

a {
    font-weight: bold;
    text-decoration: none;
    &:hover { text-decoration: underline; 
    }
    body.firefox & { font-weight: normal; 
    }
}
           

編譯為:

/* css */
a {
    font-weight: bold;
    text-decoration: none; 
}
a:hover {
    text-decoration: underline; 
}
body.firefox a {
    font-weight: normal; 
}
           

3. 屬性嵌套

div {
  border: 1px solid #ccc {
  left: 0px;
  right: 0px;
  }
}
           

編譯為:

/* css */
div {
  border: 1px solid #ccc;
  border-left: 0px;
  border-right: 0px;
}
           

插值語句

#{}

通過

#{}

插值語句可以在選擇器或屬性名中使用變量:

$name: foo;
$attr: border;
p.#{$name} {
  #{$attr}-color: blue;
}
           

編譯為:

/* css */
p.foo {
  border-color: blue; }
           

資料類型

Sass支援 7 種主要的資料類型:

  • Number 類型(數字類型):

    1, 2, 13, 10px

  • String 類型(字元串類型):有引号字元串與無引号字元串,

    "foo", 'bar', baz

  • Colors類型(顔色類型):

    blue, #04a3f9, rgba(255,0,0,0.5)

  • Boolean 類型(布爾類型):

    true, false

  • 空值(Null):

    null

  • Lists 類型(清單類型):用空格或逗号作分隔符,

    1.5em 1em 0 2em, Helvetica, Arial, sans-serif

  • Maps類型,相當于 JavaScript 的 object,

    (key1: value1, key2: value2)

Sass也支援其他 CSS 屬性值,比如 Unicode 字元集,或

!important

聲明。然而Sass 不會特殊對待這些屬性值,一律視為無引号字元串。

運算

數字運算

Sass支援數字的加減乘除、取整等運算 (

+, -, *, /, %

),如果必要會在不同機關間轉換值。

關系運算

<, >, <=, >=

也可用于數字運算,相等運算

==, !=

可用于所有資料類型。

執行個體:

p {
  width: 1 + 50px;
  height: 50 * 2px;
}
           

編譯為:

/* css */
p {
  width: 51px;
  height: 100px;
}
           

除法運算

以下三種情況

/

将被視為除法運算符号:

  • 如果值,或值的一部分,是變量或者函數的傳回值
  • 如果值被圓括号包裹
  • 如果值是算數表達式的一部分
p {
  font: 20px/4px;           
  $width: 100px;
  width: $width/2;            
  width: round(2.5)/2;      
  height: (50px/2);          
  margin-left: 4px + 18px/2px; 
}
           

編譯為:

/* css */
p {
  font: 20px/4px;
  width: 50px;
  width: 1.5;
  height: 25px;
  margin-left: 13px;
}
           

顔色值運算

顔色值的運算是分段計算進行的,也就是分别計算紅色,綠色,以及藍色的值:

p {
    color: #010203 + #040506;
    color: #010203 * 2;
}
           

計算

01 + 04 = 05

02 + 05 = 07

03 + 06 = 09

01 * 2 = 02

02 * 2 = 04

03 * 2 = 06

然後編譯為:

/* css */
p {
    color: #050709; 
    color: #020406;}
           

字元串運算

p {
  content: 'sa' + 'sb';
  cursor: 'sa' - 'sb';
}
           

編譯為:

/* css */
p {
  content: "sasb";
  cursor: "sa"-"sb";
}
           

布爾運算

Sass支援布爾型的

and

or

以及

not

運算。

p {
  content: 'sa' and 'sb';
  cursor: 'sb' or 1;
  right: 1 not 2;
  clear: 'sa' or 'sb';
}
           

編譯為:

/* css */
p {
  content: "sb";
  cursor: "sb";
  right: 1 false;
  clear: "sa";
}
           

數組運算

數組不支援任何運算方式

混合-Mixins

sass中使用@mixin聲明混合,可以傳遞參數,參數名以$符号開始,mixin可以傳入參數,多個參數以逗号分開,也可以給參數設定預設值。

mixin是可以重用的一組CSS聲明。mixin有助于減少重複代碼,隻需聲明一次,就可在檔案中引用。mixin類似變量,不同的是變量存儲值,mixin存儲一組css聲明。

表達式

@mixin 名字(參數1,參數2...){
	...
}
           

調用方式:使用

@include

指令後跟mixin的名稱

執行個體:

@mixin alert ($text-color, $background) {
  color: $text-color;
  background-color: $background;
  a {
    color: darken($text-color, 10%);
  }
}
.alert-warning {
  @include alert(#555555,#c03737);
}
           

編譯為:

/* css */
.alert-warning {
  color: #555555;
  background-color: #c03737;
}
.alert-warning a {
  color: #3c3c3c;
}
           

控制語句

Sass 提供了一些基礎的控制指令,比如在滿足一定條件時引用樣式,或者設定範圍重複輸出格式。控制指令是一種進階功能,日常編寫過程中并不常用到,主要與混合指令 (mixin) 配合使用。

@if

表達式

@if 條件 {
	...
}
           

@if

的表達式傳回值不是

false

或者

null

時,條件成立,輸出

{}

内的代碼:

p {
  @if 1 + 1 == 2 { border: 1px solid; }
  @if 5 < 3 { border: 2px dotted; }
  @if null  { border: 3px double; }
}
           

編譯為:

/* css */
p {
  border: 1px solid; }
           

@if

聲明後面可以跟多個

@else if

聲明,或者一個

@else

聲明。如果

@if

聲明失敗,Sass 将逐條執行

@else if

聲明,如果全部失敗,最後執行

@else

聲明,例如:

$type: monster;
p {
  @if $type == ocean {
    color: blue;
  } @else if $type == matador {
    color: red;
  } @else if $type == monster {
    color: green;
  } @else {
    color: black;
  }
}
           

編譯為:

/* css */
p {
  color: green; }
           

@for

表達式

@for $var from <開始值> though <結束值> {
    ...
}
           

@for

指令可以在限制的範圍内重複輸出格式,每次按要求(變量的值)對輸出結果做出變動。

這個指令包含兩種格式:

  • @for $var from <start> through <end>

  • @for $var from <start> to <end>

差別在于

through

to

的含義:當使用

through

時,條件範圍包含

<start>

<end>

的值,而使用

to

時條件範圍隻包含

<start>

的值不包含

<end>

的值。另外,

$var

可以是任何變量,比如

$i

<start>

<end>

必須是整數值。

執行個體:

@for $j from 4 through 6 {
  .item-#{$j} { width: 2em * $j; }
}
           

編譯為:

/* css */
.item-4 {
  width: 8em;}
.item-5 {
  width: 10em;}
.item-6 {
  width: 12em;}
           

@each

表達式

@each $var in $list {
	...
}
           

@each

指令的格式是

$var in <list>

,

$var

可以是任何變量名,比如

$length

或者

$name

,而

<list>

是一連串的值,也就是值清單。

@each

将變量

$var

作用于值清單中的每一個項目,然後輸出結果。

執行個體:

@each $fruit in apple, banana, watermelon, strawberry {
  .#{$fruit}-icon {
    background-image: url('/images/#{$fruit}.png');
  }
}
           

編譯為:

/* css */
.apple-icon {
  background-image: url("/images/apple.png");}
.banana-icon {
  background-image: url("/images/banana.png");}
.watermelon-icon {
  background-image: url("/images/watermelon.png");}
.strawberry-icon {
  background-image: url("/images/strawberry.png");}
           

@while

表達式

@while 條件 {
	...
}
           

@while

指令重複輸出格式直到表達式傳回結果為

false

。這樣可以實作比

@for

更複雜的循環,隻是很少會用到。

執行個體:

$j: 8;
@while $j >0 {
  .item-#{$j} {
    width: 2em * $j;
  }
  $j: $j - 3;
}
           

編譯為:

/* css */
.item-8 {
  width: 16em;}
.item-5 {
  width: 10em;}
.item-2 {
  width: 4em;}
           

Partials與@import

@import

Sass 可以幫助我們減少 CSS 重複的代碼,節省開發時間。

我們可以安裝不同的屬性來建立一些代碼檔案,如:變量定義的檔案、顔色相關的檔案、字型相關的檔案等。

Sass 導入檔案

類似 CSS,Sass 支援 @import 指令。

@import 指令可以讓我們導入其他檔案等内容。

CSS @import 指令在每次調用時,都會建立一個額外的 HTTP 請求。但,Sass @import 指令将檔案包含在 CSS 中,不需要額外的 HTTP 請求。

Sass @import 指令文法如下:

@import filename;
// 例:
@import "base";
           

注意:包含檔案時不需要指定檔案字尾,Sass 會自動添加字尾 .scss。

局部檔案(Partial)

Sass源檔案中可以通過

@import

指令導入其他Sass源檔案,被導入的檔案就是局部檔案,局部檔案讓Sass子產品化編寫更加容易。

如果一個目錄正在被Sass程式監測,目錄下的所有scss/sass源檔案都會被編譯,但通常不希望局部檔案被編譯,因為局部檔案是用來被導入到其他檔案的。如果不想局部檔案被編譯,檔案名可以以下劃線 (_)開頭。

執行個體:

// _base.scss檔案
body {
  margin: 0;
  padding: 0;
}
           
// test1.scss檔案
@import "base";

@mixin alert ($text-color, $background) {
  color: $text-color;
  background-color: $background;
  a {
    color: darken($text-color, 10%);
  }
}
.alert-warning {
  @include alert(#555555, #c03737);
}
           

編譯為:

/* css */
body {
  margin: 0;
  padding: 0;
}
.alert-warning {
  color: #555555;
  background-color: #c03737;
}
.alert-warning a {
  color: #3c3c3c;
}
           

函數

表達式

@function 名稱 (參數1,參數2) {
	...
}
           

Sass 支援自定義函數,并能在任何屬性值中使用:

$grid-width: 40px;
$gutter-width: 10px;

@function grid-width($n) {
  @return $n * $grid-width + ($n - 1) * $gutter-width;
}

#sidebar { width: grid-width(5); }
           

編譯為:

/* css */
#sidebar {
  width: 240px; }
           

與 mixin 相同,也可以傳遞若幹個全局變量給函數作為參數。一個函數可以含有多條語句,需要調用

@return

輸出結果。自定義的函數也可以使用關鍵詞參數,上面的例子還可以這樣寫:

#sidebar { width: grid-width($n: 5); }
           

建議在自定義函數前添加字首避免命名沖突,其他人閱讀代碼時也會知道這不是 Sass 或者 CSS 的自帶功能。自定義函數與 mixin 相同,都支援 variable arguments

Sass 顔色函數

Sass 顔色函數可以分為三個部分:顔色設定、顔色擷取以及顔色操作。

Sass 顔色設定

函數 描述 & 執行個體
rgb(red, green, blue) 建立一個 Red-Green-Blue (RGB) 色。其中 R 是 “red” 表示紅色,而 G 是 “green” 綠色,B 是 “blue” 藍色。
執行個體: rgb(0, 0, 255);
rgba(red, green, blue, alpha) 根據紅、綠、藍和透明度值建立一個顔色。
執行個體: rgba(0, 0, 255, 0.3);
hsl(hue, saturation, lightness) 通過色相(hue)、飽和度(saturation)和亮度(lightness)的值建立一個顔色。
執行個體: hsl(120, 100%, 50%); // 綠色 hsl(120, 100%, 75%); // 淺綠色
hsla(hue, saturation, lightness, alpha) 通過色相(hue)、飽和度(saturation)、亮度(lightness)和透明(alpha)的值建立一個顔色。
執行個體: hsl(120, 100%, 50%, 0.3); // 綠色帶有透明度 hsl(120, 100%, 75%, 0.3); // 淺綠色帶有透明度
grayscale(color) 将一個顔色變成灰色,相當于 desaturate( color,100%)。
執行個體: grayscale(#7fffd4); 結果: #c6c6c6
complement(color) 傳回一個補充色,相當于adjust-hue($color,180deg)。
執行個體: complement(#7fffd4); 結果: #ff7faa
invert(color, weight) 傳回一個反相色,紅、綠、藍色值倒過來,而透明度不變。
執行個體: invert(white); 結果: black

@media

Sass 中

@media

指令與 CSS 中用法一樣,隻是增加了一點額外的功能:允許其在 CSS 規則中嵌套。如果

@media

嵌套在 CSS 規則内,編譯時,

@media

将被編譯到檔案的最外層,包含嵌套的父選擇器。這個功能讓

@media

用起來更友善,不需要重複使用選擇器,也不會打亂 CSS 的書寫流程。

.component {
  width: 300px;
  @media (width: 567px) {
    width: 600px;
    @media  (resolution: 192dpi) {
      background-image: url(/img/1.png);
    }
  }
  @media (width: 1120px) {
    width: 400px;
  }
}
           

編譯為:

/* css */
.component {
  width: 300px;
}
@media (width: 567px) {
  .component {
    width: 600px;
  }
}
@media (width: 567px) and (resolution: 192dpi) {
  .component {
    background-image: url(/img/1.png);
  }
}
@media (width: 1120px) {
  .component {
    width: 400px;
  }
}
           

繼承(@extend)

sass中,選擇器繼承可以讓選擇器繼承另一個選擇器的所有樣式,并聯合聲明。使用選擇器的繼承,要使用關鍵詞@extend,後面緊跟需要繼承的選擇器。

.class1 {
    width: 200px;
}
.class2 {
    @extend .class1;
    background-color: #000;
}
           

編譯為:

/* css */
.class1, .class2 {
  width: 200px;
}
.class2 {
  background-color: #000;
}
           

.class2

不僅會繼承

.class1

自身的所有樣式,也會繼承任何跟

.class1

有關的組合選擇器樣式,執行個體如下:

.class1 {
    width: 200px;
}
.class1 a {
    color: white;
}
.class2 {
    @extend .class1;
}
           

編譯為:

/* css */
.class1, .class2 {
  width: 200px;
}
.class1 a, .class2 a {
  color: white;
}
           

警告與錯誤

當錯誤使用函數或mixins時可以看到警告或錯誤提示資訊

$color: (
  light:#ffffff,
  dark:#000000
);

@function color($key) {
  @if not map-has-key($colors, $key) {
    @warn "在 $colors 裡沒找到 #{$key} 這個key";
  }

  @return map-get($colors, $key);
}
body {
  background-color: color(gray);
}
// 在指令行視窗顯示:
// WARNING:在 $colors 裡沒找到 gray 這個key

// 把@warn改為@error,會在css檔案中出現錯誤資訊
           

了解更多

想更多更詳細了解sass可以浏覽:

官網:Sass: Syntactically Awesome Style Sheets (sass-lang.com)

中文官網:Sass教程 Sass中文文檔 | Sass中文網