changed 3 years ago
Published Linked with GitHub

Sass

語法

Sass 語法有分兩種 分別為: SCSSSass

較為大宗的是 SCSS 語法 其寫法與原本的 css 較為相似

編譯

在網頁瀏覽器中 都只認識 css 檔案

所以寫好的 SCSS 都需要通過編譯器把它編譯成 css 檔後才能在網頁上使用

編譯的方式有三種:

  1. 打包工具(如 webpack 或 gulp) 這裡不提供教學

  2. 編輯器內建套件(如 VS Code 的 Live Sass Compiler)

  3. prepros 軟體

VS CodeLive Sass Compiler

首先開啟 VS Code 編輯器

然後點擊左側選單列最下面的方塊 icon (這是用來搜尋並安裝套件的)

點進去後在搜索框輸入 Live Sass Compiler 安裝它

接下來我們將項目資料夾拖曳到 VS Code 編輯器中

然後我們在項目資料夾中新增一個 SCSS 資料夾

SCSS 資料夾中新增一個 all.scss 檔案

開啟該 all.scss 檔 會發現下方狀態列出現了一個新的按鈕 Watch Sass 點下去即可實時編譯

(如果看不到下方狀態列 可在最上面的選單中點擊檢視選擇外觀裡面的顯示/隱藏狀態列)

這邊說明一下:

該套件是點擊後下方狀態列有出現 Watching 就表示啟動
之後每次在 .scss 檔中點擊儲存檔案 就會自動執行編譯 不需要一直點它開關編譯
編譯成功會看到狀態列 Watching 那邊出現 綠色打勾 SUCCESS
失敗的話檔案會變成紅色標題 並且下方狀態列會跳出一個區塊 顯示問題

另外附上 setting.json 設定:

{ // 以下針對 liveSassCompile 套件設定 建議同學不要直接將此段貼到你的 json 中 因為有註解會出錯 "liveSassCompile.settings.formats": [ { "format": "expanded", "extensionName": ".css", "savePath": "/css" // 這裡是設定你編譯出來的 css 檔存放資料夾 }, { "format": "compressed", // 壓縮版 "extensionName": ".min.css", // .min 表示壓縮檔 會將多餘空格與換行刪去 直接濃縮成一行 css 檔 "savePath": "/css" // 這裡是設定你編譯出來的 css 檔存放資料夾 } ], "liveSassCompile.settings.excludeList": ["**/node_modules/**", ".vscode/**"], "liveSassCompile.settings.generateMap": false, // 建議 false 這裡是把 SASS 跟 CSS 做對應行數 設完會有很多支檔案 "liveSassCompile.settings.autoprefix": ["> 1%", "last 2 versions"] // 這項套件會自動幫你加入前綴(Prefix) }

prepros 軟體

首先到 Prepros 官網 去安裝該軟體

安裝完成後打開該軟體 將項目資料夾拖曳至軟體中

然後我們在項目資料夾中新增一個 SCSS 資料夾

SCSS 資料夾中新增一個 all.scss 檔案 即可

接下來當你的 all.scss 編寫後 按下儲存

prepros 就會幫你做編譯 並在項目資料夾中生成 css 資料夾

裡面的 all.css 就是最後我們在網頁中要引入的樣式檔案了

先說 這個套件很煩會每隔一段時間跳視窗問你要不要買正式版

但我推薦這個軟體是因為他可以開手機版畫面:

  1. 點擊右上角三個 icon 的左邊第一個 icon (兩個小長方形那個 Server)

  2. 點擊 Network Preview 用手機掃 QR Code 就可以看到手機版畫面了

SCSS 語法

& 連結符

在完全重複的名稱中可以通過連結符來減少撰寫的代碼

舉例如下:

a {
  color: red;
  &:hover {
    color: pink;
  }
}

// 編譯結果如下

a {
  color: red;
}

a:hover {
  color: pink;
}

$ 變數

我們可以在檔案的最上方設定變數 並在下方代碼中使用

舉例如下:

$primary: #ff0000;
$lineH: 40px;

a {
  color: $primary;
  line-height: $lineH;
}

// 編譯結果如下

a {
  color: #ff0000;
  line-height: 40px;
}

顏色

darken(color,%) 是顏色加深

lighten(color,%) 是顏色加亮

括號中的第一個參數是顏色 可以傳入變數也可以直接傳入顏色

括號中的第二個參數的 % 則是要加深或加亮的百分比

舉例如下:

$primary: #ff0000;

.bg-dark {
  background-color: darken($primary, 20%);
}

.bg-light {
  background-color: lighten($primary, 20%);
}

.bg-base {
  background-color: $primary;
}

// 編譯結果如下

.bg-dark {
  background-color: #990000;
}

.bg-light {
  background-color: #ff6666;
}

.bg-base {
  background-color: #ff0000;
}

匯入

Sass 可以將多個小檔案匯出為一個 css 檔

這也讓我們能更好的管理代碼 將代碼分門別類

比如我們可以把變數單獨做成一支叫 _var.scss 的小檔案

(在匯入時 通常變數都放在最上面)

然後通過 @import 來將所有小檔案匯入到 all.scss

  • 小檔案的名稱最前面需加上下底線以做區分 不然編譯器會自動將該檔案編譯成一支 css 檔

  • 加上下底線的目的是讓編譯器知道這是要匯入用的 不須被編譯

  • 要注意的是 在匯入到 all.scss 時 是不需要加上下底線的

舉例如下:

// 在 all.scss 匯入 _variable.scss
@import "./variable";

a {
  color: $red;
}

css reset

Reset 是清空所有樣式

Normailze 則是保有一些預設樣式(如 li 的 list-style 等)

通常匯入時放在變數與自己撰寫的樣式中間 不要放在自己撰寫的樣式下面

@mixin

當撰寫的樣式中有很多重複的內容時 可以使用 @mixin

首先我們創建一支 _mixin.scss

然後在裡面撰寫重複的內容( @mixin 自定義名稱 { 樣式代碼 } )

比如今天有很多地方使用到了圖片取代文字

當我們建立好圖片取代文字的 mixin 後 在要使用的地方加上 @include 自定義名稱; 這行 即可

舉例如下:

@mixin hideText {
  display: block;
  text-indent: 110%;
  overflow: hidden;
  white-space: nowrap;
}

.header {
  width: 100vw;
  height: 50px;
  background-color: #fff;
  .logo {
    a {
      height: 50px;
      width: 140px;
      background: url("./img/logo.png") no-repeat;
      background-size: cover;
      @include hideText;
    }
  }
}

// 編譯結果為

.header {
  width: 100vw;
  height: 50px;
  background-color: #fff;
}

.header .logo a {
  height: 50px;
  width: 140px;
  background: url("./img/logo.png") no-repeat;
  background-size: cover;
  display: block;
  text-indent: 110%;
  overflow: hidden;
  white-space: nowrap;
}

@mixin + 變數

在設置 @mixin 時也可以往裡面添加變數

比如某個樣式中同個顏色或尺寸重複使用多次 我們可以寫成這樣

@mixin box($color, $size) {
  width: $size;
  height: $size;
  margin: $size/10;
  background-color: $color;
  border: 2px solid $color;
}

.box {
  @include box(gold, 100px);
}

.box2 {
  @include box(red, 200px);
}

// 編譯結果
.box1 {
  width: 100px;
  height: 100px;
  margin: 10px;
  background-color: gold;
  border: 2px solid gold;
}

.box2 {
  width: 200px;
  height: 200px;
  margin: 20px;
  background-color: red;
  border: 2px solid red;
}

@mixin + @content 撰寫 RWD

以下使用範例說明:

@mixin pad {
  @media (max-width: 768px) {
    @content;
  }
}

@mixin mobile {
  @media (max-width: 568px) {
    @content;
  }
}

.header {
  width: 960px;
  height: 60px;
  @include pad {
    width: 100%;
    height: 50px;
  }
  @include mobile {
    width: 100%;
    height: 40px;
  }
}

//編譯結果

.header {
  width: 960px;
  height: 60px;
}

@media (max-width: 768px) {
  .header {
    width: 100%;
    height: 50px;
  }
}

@media (max-width: 568px) {
  .header {
    width: 100%;
    height: 40px;
  }
}

@for

類似 js 中的 for 迴圈 適用於數字的 常見於隔線系統中

使用方式有兩種:

// 第一種 from...to... 只輸出 1~3
@for $i from 1 to 4 {
  .box {
    background-color: $i;
  }
}

// 輸出後如下
.box {
  background-color: 1;
  background-color: 2;
  background-color: 3;
}

// 第二種 from...through... 會輸出 1~3
@for $i from 1 through 3 {
  .box {
    background-color: $i;
  }
}

// 輸出後如下
.box {
  background-color: 1;
  background-color: 2;
  background-color: 3;
}

// scss 無法直接將變數套到樣式名稱上
// 但可以通過 #{變數} 實現
@for $i from 1 through 5 {
  .box-#{$i} {
    opacity: $i * 20%;
  }
}

// 輸出後如下
.box-1 {
  opacity: 20%;
}

.box-2 {
  opacity: 40%;
}

.box-3 {
  opacity: 60%;
}

.box-4 {
  opacity: 80%;
}

.box-5 {
  opacity: 100%;
}

@each

類似 @for 但用於字串 使用時須先定義一個集合變數

  • 該集合變數又稱 Sass map 專門用來搭配 @each 的

  • 若要抓取集合中的其中一個 需通過 map-get(集合變數名, 'key值')

如下:

// 定義的集合變數
$themes: (
  // key: value
  "primary": blue,
  "danger": red,
  "dark": #000
);

// 抓取 danger
.bg-danger {
  background-color: map-get($themes, "danger");
}

@each 使用方式如下:

$themes: (
  // key: value
  "primary": blue,
  "danger": red,
  "dark": #000
);

@each $key, $val in $themes {
  .box-#{$key} {
    background-color: $val;
  }
}

// 輸出結果如下
.box-primary {
  background-color: blue;
}

.box-danger {
  background-color: red;
}

.box-dark {
  background-color: #000;
}

@extend

這個技巧適用於多個類名中存在相同樣式時

比如格線系統中的 .col-1 ~ .col-12

在撰寫 @for 時 就可以用到 如下:

%col {
  max-width: 100%;
  padding: 0 ($gutter-w / 2);
  flex-basis: 100%;
}

@for $i from 1 to 13 {
  .col-#{$i} {
    @extend %col;
  }
}

// 輸出後
.col-12,
.col-11,
.col-10,
.col-9,
.col-8,
.col-7,
.col-6,
.col-5,
.col-4,
.col-3,
.col-2,
.col-1 {
  max-width: 100%;
  padding: 0 ($gutter-w / 2);
  flex-basis: 100%;
}

CSS/Sass 設計模式

SMACSS

base 通常用來存放基本設定(全站設定) 比如一些值些針對標籤的設定

  • base 內容可能就是 body html a 等標籤的樣式設定

layout 通常用來存放共用設定(網站設定) 比如頭部底部等在各個頁面都會出現的樣式

  • layout 內容可能就是 header footer 等樣式

  • layout 也可以處理一些共用的東西 在樣式名加上前綴詞用以辨認 .l-xxx or .layout-xxx

module 模組化的意思 比如把按鈕或表單等 做成一個模組化的樣式

  • 先設置他的基本樣式 再以基本樣式為基底修改顏色主題、大小等

  • bootstrap 來說 btn 是按鈕基本樣式 btn-primary 是修改按鈕顏色樣式 btn-lg 是修改按鈕大小樣式

  • module 會建議不要直接在樣式中指定標籤名稱(EX: .header a 會建議改為 .header-link)

OOCSS

OOCSS 的原則是 盡量避免使用繼承選擇符(如 .list > a 這種) 它追求的是可以重複使用的樣式 在任何元素上都能套用 不拘泥於要套用在指定容器下的某個元素標籤

  1. 結構與樣式分離

    結構像是元素的大小、定位

    樣式則是顏色、背景或邊框

    以 BS4 來說 .btn 就是結構 .btn-primary 則是樣式

  2. 容器與內容分離:

    容器型元件:如 .grid .card form

    內容型元件:如 button input progress-bar

CSS 命名規範

大小駝峰

大駝峰指的是所有英文字的字首都大寫 EX: LastName

小駝峰則是指第一個英文字字首小寫其餘字首大寫 EX: lastName

  • 當在設計 class 名稱時 建議將一個名稱使用大駝峰或小駝峰的方式撰寫 而不要用下底線或減號把字拆開 原因是會讓人誤以為它有兩層 舉例來說 .bookList 如果寫成 .book-list 會讓人以為在 .book 裡面有一個列表 .book-list

BEM

BEM 指的是 block, element, modifire (即區塊, 元素, 修飾符)

區塊與元素之間用兩個下底線分隔(xxx__xx) 區塊與修飾符 or 元素與修飾符之間則用兩個中線分隔(xxxxx)

假設 我們有一個 header 它身上有陰影 它裡面有 LOGO

.header 就是 header 的區塊

.header--shadow 就是 header 的修飾符

.header__logo 就是 header 的元素

再舉例來說 我們有一個 menu 它裡面有三個按鈕 選中的時候有不同的樣式

.menu 就是 menu 的區塊

.menu__item 就是 menu 的元素

.menu__item--active 就是 menu 的元素(即 .menu__item)的修飾符

自制 grid 格線系統

首先要定義:

  • 每個 col 之間間距為多少 ex: 30px

  • 整個 container 最大寬度為多少 ex: 1200px, 960px

  • 要將 col 劃分為多少格 ex: 12, 16

將間距設為變數 $gutter, 格線系統共多少格設為變數 $gridNum

設計步驟如下:

$gutter: 30px;
$gridNum: 12;
$maxW: 1200px;
// 先將所有元素設置 box-sizing 為 border-box
* {
  box-sizing: border-box; // 設定後元素的內距和邊框就不會增加元素本身的寬度
}

// 接下來設置一個最外層 container 裡面放置 row
.container {
  max-width: $maxW;
  margin: 0 auto;
  padding: 0 ($gutter-w / 2); // 補上 row 的 margin
}

// 然後設置 row 裡面放置 col
.row {
  display: flex;
  margin: 0 (-($gutter-w / 2)); // 補上 col 的 padding
  flex-wrap: wrap; // 內容超過 100% 後會換行
}

// 再設置每個 col 的樣式
.col {
  max-width: 100%;
  padding: 0 ($gutter-w / 2); // col 之間的距離
  flex-basis: 100%; // col 佔據的寬度
}

// 最後設置當寬度大於中斷點 767px 時 各自的 col 寬度多少
@media (min-width: 767px) {
  @for $i from 1 to $gridNum + 1 {
    .col-#{$i} {
      max-width: 100% * ($i / $gridNum);
      flex-basis: 100% * ($i / $gridNum);
    }
  }
}
Select a repo