0%

Sass

Sass(Syntactically Awesome StyleSheets)是一種 CSS 的擴充,是為 CSS 的超集合(透過編譯會 compiled 成傳統 CSS,讓瀏覽器可以閱讀)。使用 Sass 的出現是為了解決在大型專案時傳統 CSS 會遇到的重複、可維護性差等問題(新增了 nested rules, variables, mixins, selector inheritance 等特性)。讓開發者可以撰寫簡潔、富語意(expressive)、重複性佳(reusable)、可維護性佳和可延展性佳的 CSS 程式碼。

Syntax 語法

Sass是一個將指令碼解析成CSS的手稿語言,即SassScript。
Sass包括兩套語法。

  • SASS(學習曲線較高,檔案名稱為 *.sass)。
  1. 不使用大括弧格式。
  2. 使用縮排。
  3. 不使用分號。
  4. 不能直接使用 CSS 語法。
  • SCSS (學習曲線相對較緩,初學者建議使用 SCSS 語法,檔案名稱為 *.scss) 。
  1. 使用和CSS一樣的語法。
  2. 大括號將不同的規則分開。
  3. 使用分號將具體的樣式分開。
SASS SCSS
.button
padding: 3px 10px
font-size: 12px
border-radius: 3px
border: 1px solid #e1e4e8
.button {
padding: 3px 10px;
font-size: 12px;
border-radius: 3px;
border: 1px solid #e1e4e8;
}

編譯方式

Sass為CSS預處理器,網頁瀏覽器無法識別此格式,所以須先將Sass編譯成CSS的格式。
常見讀編譯方式有:

  1. 編譯器:prepos
  2. Gulp / webpack 等任務處理 & 打包工具。
  3. 網頁編輯器的插件: Live Sass Compiler

Comments 註解

SASS有分兩種註解,這兩種差別是在是否會被編譯出來。

// /**/
編譯顯示 不會編譯進CSS,不會顯示出來 會編譯進CSS,並顯示出來
類型 開發階段 dev 正式階段 prod
編譯後檔案容量 小,不含註解 大,包含註解

Nesting 巢狀

可以更加清晰地表示元素之間的關係。

優點:可以把輸出的CSS做整理,很快就看出語法含意。
缺點:過於多層,CSS會變得很難維護,看的時候語意不清楚。

SCSS CSS
.nav ul {
gackground: gray;
display: flex;
justify-content: spacer-between;
> li {
padding: 0 16px;
}
}

&連結詞

使用在:

  1. 偽元素「before」、「after」等
  2. 偽類「hover」「active」等。
  3. 同層但不同名稱的 class。
SCSS CSS
a {
display: block;
padding: 6px 12px;
text-decoration: none;
&::after {
content: '';
display: block;
width: 100%;
border-bottom: 2px solid #000;
}
&:hover {
gackground: aqua;
}
}

Variables 變數

Sass支援定義變數,變數可以用來儲存值,方便重複利用。
變數以美元符號($)作為開頭。變數用冒號(:)賦值。

SassScript支援四種資料類型:

  • 數值(可包括單位)
  • 字串
  • 顏色
  • 布林類型

變數可以用作函式的參數或返回值。

SCSS CSS
$blue: #3bbfce;
$margin: 16px;

.content-navigation {
border-color: $blue;
color: darken($blue, 10%);
}

.border {
padding: $margin;
margin: $margin;
border-color: $blue;
}

變數也支援運算

SCSS CSS
$blue: #3bbfce;
$margin: 16px;

.content-navigation {
border-color: $blue;
color: darken($blue, 10%);
}

.border {
padding: $margin / 2;
margin: $margin / 2;
font-size: $margin * 2;
border-color: $blue;
}

須注意幾點,如下:

  1. 建議加減乘除統一都用空格相鄰,避免編譯出現錯誤。
  2. 單位,css常見的單位類型可分為「絕對單位」和「相對單位」,如下:
絕對單位
印刷輸出的單位,如px, pt, pc, in, mm, cm…
相對單位
顯示設備的單位,如ex, em, rem…
  1. 絕對和相對單位,不能放一起運算。
  2. 相對單位不能互相運算。
  3. 絕對單位不能相乘。

單位最好不要混搭,只需用一個單位,這樣就減少出錯的機率。

字串管理

變數也能用於字串中,使用 ' ' or " ",將字串包覆中便能調用字串。
常用於字型的管理。

顏色的運算

Sass 可透過一些內建的函式來簡單地調整顏色。

  1. 亮度調整,darken & lighten

darken & lighten 是基於HSL並調整L(lightness) 。
這兩個函數在操作 hover 狀態時非常好用。

  • 降低亮度(darken)
Syntax
darken(color , %)   //已設定的顏色調暗 %
- 提高亮度(lighten)
Syntax
lighten(color , %)  //已設定的顏色調亮 %
  1. 色調與陰影 Tint & Shade
  • 混合白色色調(Tint)
@function tint($color, $percentage) {
@return mix(white, $color, $percentage);
}
Syntax
tint( $base-color, % )
- 混合黑色色調(Shade)
@function shade($color, $percentage) {
@return mix(black, $color, $percentage);
}
Syntax
shade( $base-color, % )

變數預設值 !default

可以在變數尚未賦值前,通過在值的最後處添加 !default 標記來為其指定。
也就是說,如果該變數已經被賦值,就不會再次賦值;但是,如果還沒有被賦值,就會被指定一個值。

Interpolation 插值

插值語法可以被用於幾乎所有的 Sass stylesheet 去崁入規則於CSS內。
只要將表達式包裹進 #{}

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

At-rule 規則

Sass 支持所有 CSS3 的 @ 規則, 以及一些 Sass 專屬的規則,也被稱為“指令(directives)”。 這些規則在 Sass 中具有不同的功能。

@import

Sass 擴充了 CSS 的 @import 規則,讓它能夠引入 SCSS 和 Sass 文件。 所有引入的 SCSS 和 Sass 文件都會被合併並輸出一個單一的 CSS 文件。
另外,被導入的文件中所定義的變數或 mixins 都可以在主文件中使用。

@import "_foo.scss";
//or
@import "_foo";
//兩者都將引入 foo.scss 檔案

常見錯誤(SCSS):

  1. 結尾為加入分號。
  2. 載入錯誤,可能為名稱錯誤,或者在載入的順序相反。

但在少數幾種情況下,它會被編譯成 CSS 的 @import 規則:

  1. 如果檔案的副檔名是 .css。
  2. 如果檔案名以 http:// 開頭。
  3. 如果檔案名是 url()。
  4. 如果 @import 包含了任何 media queries。
SCSS CSS
@import "foo.css";
@import "foo" screen;
@import "http://foo.com/bar";
@import url(foo);
@import "foo.css";
@import "foo" screen;
@import "http://foo.com/bar";
@import url(foo);

CSS Reset - meyerweb 與 Normalize 的差異

開發網頁時,瀏覽器會自帶預設的樣式,如果要將樣式清除,必須重新寫CSS檔案來清空樣式,如今已經有現成的可供使用,分別為 meyerweb & Normalize,以下為兩者的差異。

  1. meyerweb - 將所有瀏覽器的樣式全數清空
  2. Normalize
  1. 保留有用的瀏覽器默認設置,而不是將其刪除。
  2. 為廣泛的 HTML 元素提供一般化的樣式。
  3. 修正瀏覽器的 Bug 與不一致。
  4. 透過微妙的改善提高可用性。
  5. 有詳細的文檔來解釋代碼。(每個樣式都有註解是處理什麼問題。)

Partials

如果有一個 SCSS 或 Sass 檔案需要引入, 但又不希望它被編譯為一個 CSS 檔案,這時,你就可以在檔案名前面加一個下底線 _,就能避免被編譯。
這將告訴 Sass 不要把它編譯成 CSS 檔案。 然後就可以像往常一樣引入這個檔案了,並且還可以省略掉檔案名前面的下劃線。

有一個檔案叫做 _colors.scss。 這樣就不會生成 _colors.css 檔案了, 而且還可以使用

@import "colors";
來引入 _colors.scss 檔案。

注意,在同一個目錄下不能同時存在帶下底線和不帶下底線的同名檔案。

@mixin and @include

讓你不會回想原理,而中斷思緒

  • 使用時機:需要大量重複使用到的屬性。
  • 使用目的:建立專屬語法資料庫。
  • @minix 需對應 @include
Syntax
@mixin 名稱 { 語法內容 };    /* 建立 */

.selector {
@include 名稱; /* 引入@mixin */
}

範例:

// 隱藏文字
@mixin hide_text {
text-indent: 101%;
white-space: nowrap;
overflow: hidden;
}
// 引入
.logo {
background-image: url(....);
@include hide_text
}

帶入參數

Syntax
/* 變數可設多個 */
@mixin 名稱 ($var1, $var2,...) {
css語法:$var1;
css語法:$var2;
};
/* 引入 */
selector {
@include ($var1, $var2,...) 名稱
}

@include 名稱後面的小括號內設定參數數值,需依照 @mixin 所設定的變數順序來設定數值;
如無照順序的情況下,SASS編譯不會出現錯誤,但會讓網頁排版錯誤。

參數預設值

@mixin 帶入的參數是可以設定預設值的,但是有設定預設值的參數需排列在最後方,否則sass編譯時會出現error。
Required argument $max-width must come before any optional arguments.

Syntax
@mixin grid($max-width, $flex: true) {
// code here
}

參數的變數

在Sass裡,變數可以為多個值的集合,稱為 list ,如果要將 list 帶入 padding 等可以有多值的屬性。

SCSS CSS
@mixin padding($values) {    
@each $var in $values {
padding: #{$var};
}
}
a {
@include padding(2px 4px 6px);
}
a {
padding: 2px;
padding: 4px;
padding: 6px;
}
可以改成,使用展開參數 ... 加在變數的後方。

展開參數

SCSS CSS
@mixin padding($values...) {    
@each $var in $values {
padding: #{$var};
}
}
a {
@include padding(2px 4px 6px);
}
a {
padding: 2px 4px 6px;
}

另外一種方式,定義兩個變數,分別為 list and map,並定義一個 mixin 可帶入3個參數。
此兩個變數皆使用 展開參數 帶入。

SCSS CSS
$style1: 100%, 70px, #fo6d06;
$style2: (background: #bada55, width: 100%, height: 100px);
@mixin box($width, $height, $background) {
width: $width;
height: $height;
background-color: $background;
}
.fogdog {
@include box($style1...);
}
.badass {
@include box($style2...);
}
.fogdog {
width: 100%;
height: 70px;
background-color: #fo6d06;
}

.badass {
width: 100%;
height: 100px;
background-color: #bada55;
}
  • 在 list 的情況下
    1. 當 list 內有3個項目,且 mixin 須帶入的參數也為3個時,每一個參數皆會依順序分別的帶入,順序不能有錯,不然會造成網頁排版錯誤
    2. 如 list 項目小於3個時,編譯時會出現錯誤。
    3. 當 list 項目大於3個時,編譯時只會取前3個。
  • 在 map 的情況下
    1. 與 lsit 相同,但例外的點為,mpa 內的 key values 會對應變數名稱。

與響應式搭配

Syntax
/* 建立 */
@mixin + 名稱 {
@media (裝置寬度) {
@content
}
};
/* 引入 */
selector {
@include + 名稱() {
內容
};
}
  1. @media 裡面只要填 @content
  2. @include + 名稱() 引入, 裡面填上 @media 的css樣式。
範例:
SCSS CSS
@mixin pad {
@media (max-width: 768px) {
@content
}
}
.header {
font-size: 24px;
@include pad {
font-size: 16px;
};
}
.header {
font-size: 24px;
}
@media (max-width: 768px) {
.header {
font-size: 16px;
}
}

@content

@content 的用途主要是拿來傳遞樣式到 @Mixin 裡面去。

@function

使用時機:搭配變數和mixin使用。

使用流程如下:

  1. 給予「變數」設定基礎數值。
/*設定變數基礎數值*/
$basePadding: 10px;
  1. 給予function名稱,讓scss可套用。
@function padding() {}
  1. function內新增參數並設定預設值。
@function padding( $index: 1) {}
/*小括弧內為參數,在此為$變數: 1 ,預設值為 1 */
  1. function內設定運算公式。
@function padding( $index: 1) {
@return $basePadding * $index;
}
  1. 引入function。
selector {
css樣式: function名稱 (參數);
}
  • funtion接多個參數

可把「變數」放在裡面。

@function padding( $index: 1, $basePadding: 10px) {
@return $basePadding * $index;
}

selector {
css樣式: function名稱 ($index, $basePadding);
}

@extend

sass中extend 是用來把css中重複的樣式作模組化,未來如要修改語法,只要改一次就能全部修改。

  • 新增extend內容
    1. 增加extend名稱,格式使用「.」+名稱,裡面放重複的樣式。
    2. 在class或是id內的樣式放上 @extend + extend 名稱
SCSS CSS
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
.error, .seriousError {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
border-width: 3px;
}

進階使用

mixin和function: 運算程式模組化

  1. 設定變數 $basePadding,他的值為 10px。
  2. 建立名叫做 padding的 @function,為運算程式,預設值為 1 。
  3. @function 內容裡面分兩部分: @if@return
  4. 使用 @mixin,裡面的內容是 @function,如果有多個 @function,可一次全部帶入到css中。
SCSS CSS
//建立程式
$basePadding: 10px;
@function padding( $index: 1) {
@if $index < 1 {
$index: 1;
}
@return $basePadding * $index;
}
@mixin a ( $index:1 ) {
padding-left: padding($index);
padding-right: padding($index);
};

//引入
.px {
@include a(3)
}
.px {
padding-left: 30px;
padding-right: 30px;
}

Flow control 流程控制

@if and @else

@if 用在判斷條件如果符合,就執行內容。
@else 是如果在 @if 中不符合條件,則執行 @else 的內容。

Syntax
@if (expression) { ... }
@else { ... }

@each

Syntax
@each $var in ( list or map ) {}
  • With list

list是一個SassScript表達式。

SCSS CSS
@each $var in ( normal, bold  ) {
.font-#{$var} {
font-weight: $var;
}
}
  • With Maps

Maps是Sass Maps,於Sass 3.3所提供另一種變數的設定方式。
類似 json 內 keyvalue 的概念。
$name就是map裡面,key 的值 (normal, …)。
$value就是map裡面,value 的值 (flex-start, …)。

SCSS CSS
$flex_posi: ( 
"normal":"flex-start",
"end":"flex-end",
"center":"center",
"between":"spacer-between",
"rounder":"spacer-rounder"
);
@each $name, $value in $flex_posi {
.justify-content-#{$name} {
justify-content: $value;
}
}

@for

sass for迴圈有兩種語法 :

  • 從start開始到end結束
Syntax
@for $var from (start) through (end)
@for $var from <start> through <end>

從整個循環都跑一遍。
透過 #{ } 轉為css可用的數值。

SCSS CSS
@for $var from 1 through 5 {
.padding-#{$var} {
padding: 10px * $var;
}
}
  • 從start開始,碰到end就結束
Syntax
@for $var from (start) to (end)

start 開始碰到 end 就結束,所以沒有套用到 end
因此大部分使用sass的for迴圈都是使用 @for $var from through

SCSS CSS
@for $var from 1 to 5 {
.padding-#{$var} {
padding: 10px * $var;
}
}
@for $i from 1 through 5 {
.box-#{$i} {
background-color: darken(#c1dfc4, $i * 10%);
}
}
@for

@while

while 只要條件符合 true ,就會一直跑下去,除非手動停止,否則很容易形成無限迴圈也因此稍有不慎會影響電腦效能。

Syntax
@while (expression) { ... }
@function scale-below($value, $base, $ratio: 1.618) {
@while $value > $base {
$value: $value / $ratio;
}
@return $value;
}

$normal-font-size: 16px;
sup {
font-size: scale-below(20px, 16px);
}