# W4 :::info 【來源】 > <https://discord.com/channels/801807326054055996/1136176662388670635/1136176662388670635> ::: --- [TOC] --- :::info 第四週設計稿(第三週設計稿改為多頁式): [W3 \- 眼鏡官網.v3 (adobe.com)](https://xd.adobe.com/view/5b20cbc4-5c64-4b67-814e-633b078a8cd4-0e73/specs/ "W3 - 眼鏡官網.v3 (adobe.com) (https://xd.adobe.com/view/5b20cbc4-5c64-4b67-814e-633b078a8cd4-0e73/specs/)") ::: 由於多頁式網站的頁面非常多,所以會推薦同學使用 SCSS 的變數來管理網站樣式。 使用變數的優點是,只需要調整變數的值,就可讓所有使用該變數的 CSS 屬性跟著改變值。 :::info [範例程式碼](https://codepen.io/izumi-dev/pen/XWyqpqQ "範例程式碼(https://codepen.io/izumi-dev/pen/XWyqpqQ)") ::: 使用 SCSS 變數 ---------- 我們可以建立一個 _variables.scss 檔案,來放專門變數的樣式,以後要更動變數的值時,就可以直接從這支檔案來做更動。 例如下方是設定變數的範例: ```SCSS! //_variables.scss // 文字大小設定 $font-size-base: 1rem; // 16px $font-size-sm: $font-size-base * 0.875; // 14px $h1-font-size: $font-size-base * 4; // 64px $h2-font-size: $font-size-base * 3; // 48px $h3-font-size: $font-size-base * 1.75; // 28px $h4-font-size: $font-size-base * 1.5; // 24px $h5-font-size: $font-size-base * 1.25; // 20px $h6-font-size: $font-size-base; // 16px // 色彩設定 $primary: #aa0601; $primary-light: #fbf2f2; $primary-dark: #650300; $secondary:... $danger:... $warning:... ``` ### 文字大小設定 基本文字大小會設定為 1rem,接著其他的文字大小,則依據 $font-size-base 的值來依照倍數放大或縮小。 ### 色彩設定 範例中的網頁主色的變數名稱,並沒有直接使用顏色($red、$blue、$green….)來命名,而是使用 $primary (primary 意思為「主要的」)、$secondary、$danger…這類,比較抽象的變數名稱。 ```SCSS! // 第一種 $red: #aa0601; // 第二種 $primary: #aa0601; ``` --- 雖然設計稿的主色 #aa0601 是紅色系,但是第一種變數寫法 $red 會遇到一個問題: 假如未來我們想要把網站的主色換為藍色系 #0080ff 的話,需要寫成 $red: #0080ff; 可是變數 $red 指的是紅色,右方的值卻寫了藍色系色碼的 #0080ff,這樣變數名稱和 CSS 的值就會有衝突。 所以主色的變數名稱,建議要使用抽像一點的形容詞,例如 $primary。 優點是,未來想換掉網站主色系時就可以直接換掉色碼,不會有名稱上的衝突感。 ```SCSS! // 假如未來想換成藍色的 #0080ff,就直接改色碼即可,像這樣 $primary: #0080ff; ``` ```SCSS! // 使用範例 .bg-primary { backgroud-color: $primary; } ``` ```htmlembedded! <div class="bg-primary">...</div> ``` ## 間距的設定(可使用 SCSS 迴圈) 由於響應式網頁的元素,在不同寬度的裝置,可能遇到不同的間距的情況。 所以會需要針對不同斷點來寫出不同的間距變化。 class 命名規則通常是 CSS屬性-斷點-值 。(命名規則參考 Bootstrap) 舉例來說, 假如 CSS 屬性為 margin-bottom、斷點為 md(平板 768px)、數值為 24px 時會寫成 .mb-md-6。 (助教這裡會以每 4px 為一個單位,所以是 24 / 4 = 6,最後寫成 .mb-md-6) ```htmlembedded! <!-- PC 版型時 margin-bottom: 12px 768px 以下時變為 margin-bottom: 16px 375px 以下時變為 margin-bottom: 8px --> <div class="mb-3 mb-md-4 mb-sm-2">...</div> ``` 但是要寫這麼多用來推間距的 class,手寫會消耗非常多時間。 這時可以善用 SCSS 的迴圈來製作出不同的間距。 :::info 範例程式碼: [SCSS for 迴圈做出間距,搭配斷點](https://codepen.io/izumi-dev/pen/rNQvMYx "SCSS for 迴圈做出間距,搭配斷點(https://codepen.io/izumi-dev/pen/rNQvMYx)") ::: ### mixin 接下來是關於 SCSS 的 mixin 功能~ ! 寫響應式網頁時,每次都要寫「 `@media(max-width: 768px)`」… 的話,也是一個非常長又繁瑣的寫法,同學可以嘗試使用 `@mixin` 來簡化程式碼,範例: ```SCSS! // pad 和 mobile 是自己定義的名稱 @mixin pad{ @media(max-width: 768px){ @content; } } @mixin mobile{ @media(max-width: 375px){ @content; } } // 使用方式 .header{ @include pad { ... } @include mobile { ... } } ``` 以 container mixin 的寫法為例的話,會像這個樣子: ```SCSS! // 上週的寫法 .container { /* 桌機 */ max-width: 1320px; margin: 0 auto; padding: 0 12px; /* 平板 */ @media (max-width: 768px) { max-width: 720px; } /* 手機 */ @media (max-width: 375px) { max-width: 372px; } } // 改為 mixin 寫法 .container { max-width: 1320px; margin: 0 auto; padding: 0 12px; @include pad{ max-width: 720px; } @include mobile{ max-width: 372px; } } // 註:斷點設定為示意用,常用斷點可以參考看看 Bootstrap // https://bootstrap5.hexschool.com/docs/5.0/layout/breakpoints/ // https://bootstrap5.hexschool.com/docs/5.0/layout/containers/ ``` 小建議: mixin 也可以獨立成一個 SCSS 檔案 _mixin.scss 唷~ 有依照功能分類會比較好搜尋 ```SCSS! // _mixin.scss @mixin pad{ @media(max-width: 768px){ @content; } } @mixin mobile{ @media(max-width: 375px){ @content; } } ``` 程式碼有分類~ 在管理上也會比較方便哩 --- ### 將 SCSS 集中到 all.scss 來做管理 上述我們寫的檔案 _variables.scss、_mixin.scss …這些前面有下底線的檔案,需要在 all.scss 這支檔案使用 @import 來引入,最後才能被一起編譯出來。 例如: **all.scss** ```SCSS! // @import "檔案的路徑" // 此為示意,同學手寫 CSS 的作業的專案資料夾結構不一定相同,需要注意引入的路徑是否正確 @import "variables" // 變數 @import "reset" // CSS Reset @import "base" // 全站樣式 img{}, body{} @import "mixin" // mixin // 頁面 @import "index" ``` 小補充: 使用 @import 引入 時,檔名前面的下底線和副檔名 .scss 可以被省略。 (_variables.scss ⇒ variables) 另外,引入的順序也是等於編譯的順序,所以要留意引入的 SCSS 檔案的順序。 變數檔案可以放在上方,避免其他的 SCSS 檔案找不到變數而讓程式跳錯。 (引入的順序很重要喔! :::info SCSS 依照資料夾分類的方式,可以參考看看文章: [淺談 CSS 設計模式系列-Sass 7-1 Pattern 篇 | 是 Ray 不是 Array (israynotarray.com)](https://israynotarray.com/css/20200523/116058774/ "淺談 CSS 設計模式系列-Sass 7-1 Pattern 篇 | 是 Ray 不是 Array (israynotarray.com)(https://israynotarray.com/css/20200523/116058774/)") ::: --- ### SCSS 避免不建議超過 4、5 層 接下來是關於 SCSS 的寫法~ 有一些需要注意的點。 我們撰寫 SCSS 時要避免寫太多層,SCSS 層數過多時會影響效能,同時也會讓程式碼難以閱讀。 以上週程式碼的導覽列為例: ```htmlembedded! <nav class="navbar"> <div class="navbar-wrap"> <a class="navbar-logo" href="#"> <img src="..." alt="logo"> </a> <ul class="navbar-nav"> <li class="navbar-item"><a class="navbar-link" href="#">系列鏡框</a></li> ... </ul> </div> </nav> ``` 太多層: ```SCSS! .navbar { ... .navbar-wrap { ... .navbar-nav { ... .navbar-item { ... .navbar-link { // ... 太多層了吧...Q_Q } } } } } ``` 可以將內層 class 整理出來,減少層數: ```SCSS! .navbar { ... .navbar-wrap { ... } .navbar-nav { ... } .navbar-item { ... } .navbar-link { ... } } ``` 如此一來,navbar 內層元素同樣吃的到樣式,程式碼會比較容易閱讀,結構也會變得非常清楚。 而如果同學之前習慣使用標籤來寫樣式的話:像是 .navbar a 這樣的寫法就比較難做到這樣子的結構規劃。 所以使用 SCSS 時,建議同學盡量少用標籤來寫樣式。 ```htmlembedded! <nav class="navbar"><a class="navbar-link" href="#">我是連結</a></nav> ``` ```SCSS! // 較不明確,且有影響 .navbar 內其他 a 標籤的可能性 .navbar a // 改為運用 class 來寫樣式 .navbar .navbar-link ``` --- 專案 layout 的 ejs 檔案 設計稿中,每頁都有出現的布局(例如最上方導覽列、footer)可以寫在 .ejs 檔案。 以課程提供的起始專案(詳見課程章節「GGV 任務 - 前端任務管理工具教學」)為例,可以藉由 ejs 的語法 include 來將 ejs 檔案引入到需要使用的 html 頁面,<%- include('要引入的 ejs 檔案的路徑'); -%>。 這樣就不需要每一頁都寫一次導覽列和 footer 的程式碼。 總結 -- 撰寫多頁式網頁 SCSS 時: - 設定 SCSS 變數的名稱時,可以使用抽象一點的命名。主色是紅色系的話不建議使用 $red 這樣的寫法,可改為 $primary (primary,主要的、代表「主色」)。 - 也可以運用 SCSS 迴圈的方式來寫出各種斷點的間距,.mb-md-2、.mr-sm-8 ……。 - @media(max-width: …px) 寫起來比較繁瑣,遇到比較繁瑣又一直重複的寫法時,可以嘗試使用 mixin 來將樣式做包裝。 :::info [mixin 可以應用於背景圖的範例程式碼](https://codepen.io/izumi-dev/pen/zYMjZWB "mixin 可以應用於背景圖的範例程式碼(https://codepen.io/izumi-dev/pen/zYMjZWB)") ::: - SCSS 不建議太多層,建議善用 class 來安排結構。 祝同學都能順利地運用這些 SCSS 技巧,完成第四週主線o(°▽°)o!
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up