iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
Vue.js

業主說給你30天學會Vue系列 第 10

V10_在vue之前_必備的CSS基礎(3)_SASS/SCSS控制

  • 分享至 

  • xImage
  •  

V10_在vue之前_必備的CSS基礎(3)_SASS/SCSS控制

今天來探索一下有關CSS的SASS/SCSS控制

首先看一下MDN的說明
https://developer.mozilla.org/en-US/docs/Glossary/CSS_preprocessor
CSS preprocessor:A CSS preprocessor is a program that lets you generate CSS from the preprocessor's own unique syntax.

由上述的說明是一個CSS的預處理器,像是在產生最終的CSS之前,有原始的SCSS檔,然後經CSS預處理器編譯成可以被瀏覽器解析的語法,因此代表要特別去理解經過CSS preprocessor的過程可以帶來什麼方便之處。

目前比較常見的CSS preprocessor是SASS,
官網為 https://sass-lang.com/
在使用SASS之前要先安裝SASS
https://sass-lang.com/install/

下載點為
https://github.com/sass/dart-sass/releases/tag/1.68.0
點選不同系統平台的版本,下載後解壓縮後,將該路徑指定到PATH的變數中,
或是 在node.js的npm模式下
輸入安裝指令

npm install -g sass

在MacOS下可以透過Homebrew安裝
指令為

brew install sass/sass/sass

安裝後可以利用

sass --version 

查看版本是來確定是否有安裝成功。

接著以下指令為 將sass的原始檔(input.scss)編譯為css檔(output.css)

sass input.scss output.css

之後若是要在vue的專案檔使用,就可以利用npm來安裝,這樣就跟vue的安裝套件是相同的了

//-------------------------------

接下來是SCSS的語法說明
可以參考SASS官網的介紹
https://sass-lang.com/guide/

基本上 sass/scss 最主要的重點就是可以設定變數,以及一些像是程式般的控制css的屬性
因此,如何增加css設定的彈性以及好維護,就是在使用scss時要一直思考的項目,
而不是為了使用scss而產生更多的工作出來。

先從範例來看範如何使用

編譯前
SCSS

$font-stack: Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}

以及
SASS

$font-stack: Helvetica, sans-serif
$primary-color: #333

body
  font: 100% $font-stack
  color: $primary-color

以上可以看到有2種SASS格式,最初是使用SASS的格式,就是以縮排的方式來排列SASS的內容,
由於SASS是以Ruby程式語言開發的,而Ruby程式語言的編寫風格就是不使用大括號來界定程式區段的範圍,
而是以縮排的方式界定程式區段的範圍,這種風格也出現在Python程式語言中。
因此SASS就做用了縮排的方式來排列SASS的內容,

不過畢竟是CSS相關,因此另外推出SCSS的格式,也就是使用與CSS相同的以大括號來界定樣式區段的範圍,
這樣在編輯SCSS檔案時,不會差距太大,也算是像是在編寫可程式化的CSS檔的效果
所以SASS或是SCSS指的都是CSS預處理的格式檔案,預處理編譯器則是SASS

然後
編譯後
CSS

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

以下列出一些常見的SCSS的用法

樣式巢狀處理
SCSS

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }
  li {
    display: inline-block;
  }
  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

編譯後
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;
} 

可以看出,原本的CSS是不能有巢狀關係的,只能用並列的方式來表示上層與下層的關係
在SCSS中,可以用像是物件屬性的方式,來表示上層與下層的關係

再來是@import的用法,一種可以外部scss檔案匯入的概念,像是全域的樣式匯入

reset.scss

html, body, ul, ol {
  margin: 0;
  padding: 0;
}

standard.scss

@import "reset";

body {
  font-family: Helvetica, sans-serif;
  font-size: 18px;
  color: red;
}

編譯後
CSS

html, body, ul, ol {
  margin: 0;
  padding: 0;
}

body {
  font-family: Helvetica, sans-serif;
  font-size: 18px;
  color: red;
}

//-----------------
接著是 @mixin 與 @include 的搭配使用, 比較像是區域的樣式引入

mystyle.scss

@mixin important-text {
  color: red;
  font-size: 25px;
  font-weight: bold;
  border: 1px solid blue;
}

.danger {
  @include important-text;
  background-color: green;
}

編譯後 CSS
mystyle.css

.danger {
  color: red;
  font-size: 25px;
  font-weight: bold;
  border: 1px solid blue;
  background-color: green;
}

由上可看出 @mixin 像是一個樣式的片段,等著被其他的主要樣式加入或併入
就是 important-text 的樣式片段 加入 @include 到 .danger 樣式中

也可以是有參數帶入的形式


@mixin square($size, $radius: 0) {
  width: $size;
  height: $size;

  @if $radius != 0 {
    border-radius: $radius;
  }
}

.avatar {
  @include square(100px, $radius: 4px);
}

編譯後 CSS

.avatar {
  width: 100px;
  height: 100px;
  border-radius: 4px;
}

//---------------
再來是 @extend 的用法
SCSS

.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 的概念,像是將 .button-basic 引入到 .button-report中
但就編譯後的結果來看,像是將 .button-report 並列到 .button-basic,
有點像是註冊或是掛載到 .button-basic,這樣 .button-basic 的變化就會同步到 .button-report 及 .button-submit中了

//------------------------

接下來,在SCSS中也有支援一些funtion的使用,這個像是原本要使用js控制一些元素的屬性變化,就可以在SCSS檔案中處理了。
分成幾種不同類別的function

有 String,Numeric,List,Map,Selector,Introspection,Color
這些可以看作是原本CSS function 以及 selector function 的擴充

需要使用 @use 來載入function的套件

舉例來說

str-length("Hello world!")
Result: 12

計算字串長度

str-index("Hello world!", "H")
Result: 1

找出字元出現在字串中的位置
要注意的是回傳第一位置的字元的索引index是1 不是0

comparable(15px, 10px)
Result: true --> 同單位,可比較
comparable(35px, 2em)
Result: false --> 不同單位,不可比較

這個是在檢查,這2個數值是否為可比較的數值

random()
Result: 0.45673

取得 0 ~ 1之間的隨機數值

$font-sizes: ("small": 12px, "normal": 18px, "large": 24px)
map-get($font-sizes, "small")
Result: 12px

取得在 $font-sizes中,"small"的數值

這部份的使用地方比較是在樣式屬性的數值設定上需要的一些運算及處理。

這些內建的套件模組有

The sass:math module 數值的操作.
The sass:string module 字串的合併,搜尋,分段
The sass:color module 顏色的操作
The sass:list module 清單的操作,比較像是陣列的操作
The sass:map module 物件(key_value)map 的操作
The sass:selector module 選擇器的操作
The sass:meta module SASS 內部資訊的查詢

以下是一些完整的使用範例
SCSS

$sizes: 40px, 50px, 80px;

@each $size in $sizes {
  .icon-#{$size} {
    font-size: $size;
    height: $size;
    width: $size;
  }
}

這個使用到@each,像是loop的概念,可以一次產出不同 $sizes 的icon 樣式

編譯後 CSS

.icon-40px {
  font-size: 40px;
  height: 40px;
  width: 40px;
}

.icon-50px {
  font-size: 50px;
  height: 50px;
  width: 50px;
}

.icon-80px {
  font-size: 80px;
  height: 80px;
  width: 80px;
}

//--------

SASS 有提供 playground 可以測試SCSS 的結果
https://sass-lang.com/playground/

https://ithelp.ithome.com.tw/upload/images/20230924/20152098mHc2ZA31xA.png

還有完整的文件說明
https://sass-lang.com/documentation/

//---------
另一個範例
SCSS

@use "sass:meta";

@mixin syntax-colors($args...) {
  @debug meta.keywords($args);
  // (string: #080, comment: #800, variable: #60b)

  @each $name, $color in meta.keywords($args) {
    pre span.stx-#{$name} {
      color: $color;
    }
  }
}

@include syntax-colors(
  $string: #080,
  $comment: #800,
  $variable: #60b,
)

編譯後 CSS

pre span.stx-string {
  color: #080;
}

pre span.stx-comment {
  color: #800;
}

pre span.stx-variable {
  color: #60b;
}

Console 訊息

@debug:4 (string: #080, comment: #800, variable: #60b)

@debug 相當於 console.log();
$args... 是指 參數列

https://ithelp.ithome.com.tw/upload/images/20230924/20152098brZEHCc6Rc.png


上一篇
V09_在vue之前_必備的CSS基礎(2)_排版控制
下一篇
V11_快速檢視Vue的功能(1)_v-bind 綁定操作
系列文
業主說給你30天學會Vue31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言