[Sass]學習筆記
Sass (英文全稱:Syntactically Awesome Stylesheets) 是一個最初由Hampton Catlin 設計並由Natalie Weizenbaum 開發的層疊樣式表語言。
Sass 是一個CSS 預處理器。Sass 是CSS 擴展語言,可以幫助我們減少CSS 重複的代碼,節省開發時間。Sass 完全兼容所有版本的CSS。Sass 擴展了CSS3,增加了規則、變量、混入、選擇器、繼承、內置函數等等特性。Sass 生成良好格式化的CSS 代碼,易於組織和維護。
寫完 Sass 透過編譯成CSS給瀏覽器讀取的優點:可以寫較少的程式碼、可讀性高、提供巢狀結構和變數管理及運算功能、模組化好維護。
為什麼使用Sass?
Sass 是一款強化 CSS 的輔助工具,它在 CSS 語法的基礎上增加了變量 (variables)、嵌套 (nested rules)、混合 (mixins)、導入 (inline imports) 等高級功能,這些拓展令 CSS 更加強大與優雅。使用 Sass 以及 Sass 的樣式庫(如 Compass)有助于更好地組織管理樣式文件,以及更高效地開發項目。
CSS 本身語法不夠強大,導致重複編寫一些代碼,無法實現復用,而且在代碼也不方便維護。
Sass 引入合理的樣式複用機制,增加了規則、變量、混入、選擇器、繼承、內置函數等等特性。以下整理 Sass 特性。
註解
Sass 的註解有兩種,/* */
和 //
。
兩者不僅僅是多行註解與單行註解的差異,//
是不會被編譯出來的。
Nesting:巢狀
降低父元素重複性。
轉譯後的 CSS 樣式:
.parent {
color: blue;
}.parent .child {
font-size: 12px;
}
轉譯前:
.parent {
color: blue;
.child {
font-size: 12px;
}
}
這樣如果需要修改 .parent
名稱,就只需要改一個地方。
要避免過度巢狀,如果包太多層,選擇器階層性過長,會導致瀏覽器渲染時間會比較久。
Sass 嵌套規則與屬性
Sass 嵌套 CSS 選擇器類似於 HTML 的嵌套規則。
如下我們嵌套一個導航欄的樣式:
Sass 代碼:
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li {
display: inline-block;
}
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}
實例中,ul, li, 和 a 選擇器都嵌套在 nav 選擇器中,將以上代碼轉換未 CSS 代碼,如下所示:
Css 代碼:
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav li {
display: inline-block;
}
nav a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
Sass 嵌套属性
很多 CSS 屬性都有同樣的前綴,例如:font-family, font-size 和 font-weight , text-align, text-transform 和 text-overflow。在 Sass 中,我們可以使用嵌套屬性來編寫它們:
Sass 代碼:
font: {
family: Helvetica, sans-serif;
size: 18px;
weight: bold;
}text: {
align: center;
transform: lowercase;
overflow: hidden;
}
將以上代碼轉換未 CSS 代碼,如下所示:
Css 代碼:
font-family: Helvetica, sans-serif;
font-size: 18px;
font-weight: bold;text-align: center;
text-transform: lowercase;
text-overflow: hidden;
Variables:變量
Sass 支援定義變數。變數以美元符號($
)作為開頭。變數用冒號(:
)賦值。
變數的資料型態可以是 Numbers(可以有單位或無單位)、Strings、Booleans、null 值(視為空值),甚至可以使用 Lists、Maps 。
$text-color: #f00;
1. 變數使用時機
變數使用時機:
- 全域樣式設定
- 時常需要設定的樣式
如果需要修改樣式時,只需要修改變數的數值,就可以快速修改全部網頁的樣式,不需要逐一修改程式碼。
2. 變數格式
- 數字,
1, 2, 13, 10px
- 字符串,有引號字符串與無引號字符串,
"foo", 'bar', baz
- 顔色,
blue, #04a3f9, rgba(255,0,0,0.5)
- 布林類型,
true, false
- 空值,
null
- 數組 (list),用空格或逗号作分隔符,
1.5em 1em 0 2em, Helvetica, Arial, sans-serif
- maps, 相當于 JavaScript 的 object,
(key1: value1, key2: value2)
比較常用的為前三項。
數值
$flex: 2;
$fontsize-m: 16px;
字串
$ffm: "'Noto Sans TC', sans-serif";
$imge: '../../photo.png';
顏色
$white: white;
$color-1: #FFF000;
$color-2: rgb(0, 0, 0, .5);
運算
Sass 支持數字的標準運算(加 +
、減 -
、乘 *
、除 /
和取餘 %
),並且,如果需要的話,也可以在不同單位間做轉換:
// scss
p {
width: 1in + 8pt;
}/* 編譯 css */
p {
width: 1.111in;
}
Sass 的陣列
雖然說陣列的英文應該是 Array,但是 Sass 裡面只有 List,但用法相同。
Sass 的陣列索引是從 1 開始,陣列通常是用來存放沒有鍵名的變數。
$color: #000, #FFF, #222;// 透過 nth() 使用 List。
p {
color: nth($color, 2);
}
// 當然你也可以傳入索引變數
$index: 3;a {
color: nth($color, $index);
}/* 編譯 CSS */
p {
color: #FFF;
}a {
color: #ABC;
}
Sass 的物件
雖然說物件的英文應該是 Object,但是 Map 裡面只有 maps,但用法相同。
Map 和 List 不同的地方在於你可以自訂每個資料的鍵名,也就是他們的名稱。
$linkColor: (
'dark': #000,
'light': #FFF,
'red': #791229,
);p {
color: map-get($linkColor, dark);
}/* 編譯 CSS */
p {
color: #000;
}
Maps function
map-get(map, key)
,取出指定的值map-merge(map1, map2)
,合併多個 mapmap-remove(map, key)
,移除指定的值map-keys(map)
,列出指定 map 的全部 keymap-values(map)
,列出指定 map 的全部 valuemap-has-key(map, key)
,確認 map 中是否有指定 key
@import
@import
可以將 CSS 程式碼切成好幾份來做檔案管理,最後編譯出來合併成一個CSS檔案,方便管理。
在檔案名稱前面加上 _
,檔案將不會被編譯,例如 _reset.sass
。
利用 Sass import 功能,就可以將程式碼切成各糢組區塊,程式碼較少,同時也較能準確聚焦欲修改的區塊。
@mixin
使用 Sass @mixin 的好處:
- 省去重複撰寫相同 CSS 樣式的時間
- 建立 CSS 技巧資料庫,快速取用
以指令 @mixin
宣告,並以指令 @include
呼叫。
如果撰寫 SASS 格式:
@mixin
為=
符號@include
為+
符號
@mixin
範例:
@mixin table-base {
th {
text-align: center;
font-weight: bold;
}
td, th {
padding: 2px
}
}#data {
@include table-base;
}/* 編譯 css */
#data th {
text-align: center;
font-weight: bold;
}#data td, #data th {
padding: 2px;
}
向混入傳遞變量
混入可以接收參數。我們可以向混入傳遞變量。
定義可以接收參數的混入:
實例
/*混入接收兩個參數*/
@mixin bordered ( $color , $width ) {
border : $width solid $color ;
}.myArticle {
@include bordered ( blue , 1px ) ; //調用混入,並傳遞兩個參數
}.myNotes {
@include bordered ( red , 2px ) ; //調用混入,並傳遞兩個參數
}
以上實例的混入參數為設置邊框的屬性(color 和width) 。
將以上代碼轉換未CSS 代碼,如下所示:
Css 代碼:
.myArticle {
border : 1px solid blue ;
}.myNotes {
border : 2px solid red ;
參數預設值
@mixin
還可以附帶參數並給予預設值,如果沒有給值就會將預設值帶入。
@mixin bordered ( $color : blue , $width : 1px ) {
border : $width solid $color ;
}
在包含混入時,你只需要傳遞需要的變量名及其值:
實例
@mixin sexy- border ( $color , $width : 1in ) {
border : {
color : $color ;
width : $width ;
style : dashed ;
}
}
p { @include sexy- border ( blue ) ; }
h1 { @include sexy- border ( blue , 2in ) ; }
將以上代碼轉換未CSS 代碼,如下所示:
Css 代碼:
p {
border-color : blue ;
border-width : 1in ;
border-style : dashed ; }h1 {
border-color : blue ;
border-width : 2in ;
border-style : dashed ;
}
@each
在@each中,定義了一個變量,其中包含列表中每個項目的值。
語句
@each $var in <list or map>
下面簡要解釋語法。
- $ each:它表示變量的名稱。@each規則將$ var設置到列表中的每個項目,並使用值$ var輸出樣式。
- <列表或地圖>:這些是SassScript表達式,將返回列表或映射。
$list 方法:
@each $color in red, green, yellow {
.p_#{$color} {
background-color: #{$color};
}
}
$map 方法:
$colors: (color1: red, color2: green, color3: yellow);
@each $key, $color in $colors {
.p_#{$color} {background-color: $color;}
}
使用each+Sass Maps來設計程式碼:
//scss程式碼
$types: (
primary : #428bca,
success : #5cb85c,
) !default;//按鈕
@each $name, $color in $types {
.btn-#{$name} {
background:$color;
color:#fff;
border: 1px solid darken($color,5%);
}
}]//編譯出來的CSS
.btn-primary {
background: #428bca;
color: #fff;
border: 1px solid #357ebd;
}
.btn-success {
background: #5cb85c;
color: #fff;
border: 1px solid #4cae4c;
}
我們一一來解析這樣的程式碼:
Sass Maps
Sass Maps是Sass 3.3所提供另一種變數的設定方式,
有點像是json富有key與value的概念,
所以一開始就把你這網站有哪些樣式整理好後,
key就寫此顏色的名稱,
valuse就寫他的色碼:
$types: (
primary : #428bca,
success : #5cb85c,
info : #5bc0de,
warning : #f0ad4e,
danger : #d9534f
)
@each
@each $name , $color in $types各別的意思是,
$types就是去讀取你的Sass Map裡面的變數,
看裡面有幾組,他的迴圈就會跑幾次。 $name、$color這兩個變數你可以自己命名,
只要知道第一個變數$name會去找冒號前面的內容,
第二個變數$color會找冒號後面的值即可。
${} 插補
變數沒辦法直接接字串,
如果你希望變數可以連結字串的話,
變數就必須使用插補包起來,
所以我each裡面迴圈的程式碼,
就可以透過插補動態產生class名稱,
所以.btn-#{$name}跑第一次迴圈時,
自然會先找到primary,組合起來就變成.btn-primary,
後面就依序組合各別的Class名稱。
@content
@content
的用途主要是拿來傳遞內容到 @mixin
裡面去的,像是一般的 @mixin
大家所認知的就是他能夠傳遞變數進去,
一般的 @mixin
如下程式碼:
@mixin bg($text-color, $bg-color) {
background: $bg-color;
color: $text-color;
}.box {
@include bg(#fff,#000);
}/* 編譯 css */
.box {
background: 000;
color: #fff;
}
使用 @content
就能在 @mixin
裡面繼續寫額外的東西
@mixin bg($text-color, $bg-color) {
background: $bg-color;
color: $text-color;
@content; // 增加一個 @content
}.box {
@include bg(#fff, #000) {
border: 1px solid lighten(#000, 10);
// 將額外的程式碼寫在 @include 中括號裡面
}
}/* 編譯 css */
.box {
background: #000;
color: #fff;
border: 1px solid #1a1a1a; /*對應 @content*/
}
舉個例子 @content
可以用在狀態樣式的表示:
// 連結樣式
@mixin link {
&:link,&:visited{
@content;
}
}// 被點擊後的樣式
@mixin link-hover {
&:hover, &:focus, &:active, &.active{
@content;
}
} .box {
height:50px;
@include link{color:#fff};
@include link-hover{color:#000};
}/* 編譯 css */
.box {
height: 50px;
}
.box:link, .box:visited {
color: #fff;
}
.box:hover, .box:focus, .box:active {
color: #000;
}
利用此方法可以不用每次都要手寫 hover
、active
、focus
的樣式。
另外 @content
的使用還可以在 media-queries、animation 的 keyframes 定義,還有為瀏覽器兼容的定義等等。
RWD 搭配 @mixin
也可以用在 RWD 斷點設計:
$pc: 1024px;
$mobile: 768px;@mixin rwd($width) {
@media (max-width: $width) {
@content;
}
}.box{
float:left;
width: 30%;
@include rwd($mobile) {
float: none;
width: 100%;
}
}/* 編譯 css */
.box {
float: left;
width: 30%;
}
@media (max-width: 768px) {
.box {
float: none;
width: 100%;
}
}
@extend
@extend
為合併樣式,將相同樣式的選擇器合併,並且可以繼續延續新增新的樣式。
@extend
語法:
.box1 {
background-color: #FFDDDD;
border: 1px solid yellow;
}
.box2 {
@extend .box1;
border-color: pink;
}/* 編譯 css */
.box1, .box2 {
background-color: #FFDDDD;
border: 1px solid yellow;
}.box2 {
border-color: pink;
}
注意合併樣式的先後順序。
.box2 {
@extend .box1;
border-color: pink;
}.box1 {
background-color: #ffdddd;
border: 1px solid yellow;
}/* 編譯 css */
.box2 {
border-color: pink;
}.box1, .box2 {
background-color: #ffdddd;
border: 1px solid yellow;
}
如果是這樣,box2
的樣式將會被覆蓋。
佔位符選擇器%foo
(Placeholder Selectors: %foo
)
從 Sass3.3 開始,可以在同一行中使用最近選擇器引用 &
來實現高級選擇器,比如:
.foo {
&-bar {
color: red;
}
}/* 編譯 CSS */
.foo-bar {
color: red;
}
種方式通常被用來配合 BEM 全名方式使用。
Sass額外提供了一種特殊類型的選擇器:佔位符選擇器 (placeholder selector)。與常用的 id 與 class 選擇器寫法相似,只是#
或.
替換成了%
。必須通過@extend指令調用。
當佔位符選擇器單獨使用時(未通過@extend
調用),不會編譯到CSS文件中。
假如我們要建立一個樣式,但又不會去呼叫它,只是用來繼承,這時可以使用 %
符號。
Sass 對這種選取項型態稱作 Placeholders,只有當使用 @extend
才會有作用。
使用 %
符號,並不會被 Sass 編譯成 CSS:
a%drink {
font-size: 2em;
background-color: $lemon-yellow;
}.lemonade {
@extend %drink;
/* more */
}/* 編譯 css */
a.lemonade {
font-size: 2em;
background-color: yellow;
}.lemonade {
/* more */
}
@extend
與 @mixin
的差異性
1. @extend
@extend
主要用於合併相同程式碼。
若程式碼中有部分的 CSS 段落都長一樣,就可以呼叫 @extend
將樣式合併,有點類似 JavaScript 的繼承。
2.@mixin
@mixin
主要用於壓縮程式碼段落。
對於許多 CSS 段落需要重複使用,建議可以使用 @mixin
整理,此外,可以透過 代入參數 的特性重複使用,有點類似 JavaScript 的多型。
@extend與繼承
@extend指令告訴 Sass 一個選擇器的樣式從另一選擇器繼承。
如果一個樣式與另外一個樣式幾乎相同,只有少量的區別,則使用@extend就可能很有用。
以下 Sass 實例中,我們創建了一個基本的按鈕樣式 .button-basic,然後我們定義了兩個按鈕樣式 .button-report 與 .button-submit ,它們都繼承了 .button-basic,它們主要區別在於背景顏色與字體顏色,其他的樣式都是一樣的。
Sass代碼:
.button-basic {
border: none;
padding: 15px 30px;
text-align: center;
font-size: 16px;
cursor: pointer;
}.button-report {
@extend .button-basic;
background-color: red;
}.button-submit {
@extend .button-basic;
background-color: green;
color: white;
}
將以上代碼轉換未 CSS 代碼,如下所示:
.button-basic, .button-report, .button-submit {
border: none;
padding: 15px 30px;
text-align: center;
font-size: 16px;
cursor: pointer;
}.button-report {
background-color: red;
}.button-submit {
background-color: green;
color: white;
}
使用 @extend 後,我們在 HTML 按鈕標籤中就不需要指定多個類 class=”button-basic button-report” ,只需要設置 class=”button-report” 類就好了。
@extend 很好的體現了代碼的複用。