--- tags: Bootstrap5 實戰營 --- <style> .main { color: #7952b3; font-weight: bolder; } </style> # Bootstrap5 最終設計稿筆記 ## 安裝 bootstrap 以修改特定樣式 要安裝有兩種方式 一個是使用 npm 另一個是進入官網點擊它的 Download 原始碼 npm 方式: 1. 創建你的項目資料夾 假設叫 bs5 2. 打開你的終端機 cd 到 bs5 資料夾 3. 輸入指令 `npm i bootstrap` 進官網下載方式: 1. 點擊進入[下載網址](https://bootstrap5.hexschool.com/docs/5.0/getting-started/download/) 2. 往下找到下載原始碼 3. 點擊後下載解壓縮 4. 找到裡面的 SCSS 資料夾把他拉到你的資料夾中使用 <span class="main">注意: 這裡要下載的不是 css 檔案而是 scss 檔案(要使用 scss 才能客製化編輯修改 bootstrap 的樣式)</span> 所以這邊不能直接點擊首頁的下載 首頁的下載是編譯完成的 css 檔與 JS 檔 ## 修改樣式 首先找到 <span class="main">scss/_variable.scss</span> 檔案 這支是修改變數的 在裡面會看到有一段代碼為: ```sass= $theme-colors: ( "primary": $primary, "secondary": $secondary, "success": $success, "info": $info, "warning": $warning, "danger": $danger, "light": $light, "dark": $dark, ) !default; ``` <span class="main">修改/添加 bootstrap 色系就在這邊</span> 這裡依照設計稿 把 $secondary $dark $warning $danger 改成設計稿的顏色 如下: ```sass= $theme-colors: ( "primary": $primary, "secondary": #858377, "success": $success, "info": $info, "warning": #FFDF65, "danger": #FF785E, "light": $light, "dark": #636057, ) !default; ``` 然後再設定 $body-color 為 #494846 (用 VS Code 在變數檔案中按 control + F 可以開啟搜尋,在搜尋框輸入 $body-color 就可以找到它) 另外 tooltips 的樣式也是從這裡直接修改 如下: ```sass= $tooltip-color: $warning !default; $tooltip-bg: $body-color !default; ``` 另外附上我的 [Sass 筆記](/@WangShuan/S1IatmG9O)以及 [Bootstrap5 實戰營第四週筆記](/y1n_hdCiQJS5nBQDhWjXCw) 裡面有講比較細的修改方式 ## 字形 <span class="main">設計稿用 Noto Sans TC 做中文字, Baloo Tamma 2 做數字與一些英文字符號</span>等。 我這邊載入 Google 字型的樣式 兩個字型放一起用|符號隔開,空格改成加號即可。 這邊附上 [Google下載字體的網址](https://fonts.google.com/) 在搜索框輸入你要找的字 然後點擊進入該字體會看到一排各種粗細的字 右邊有 + 號可以選擇 選完之後點擊畫面右上角三個正方行一個加號的 icon 按鈕就可以複製引入的代碼了~ 貼到你的 head 中後就可以直接寫 font-family: "Noto Sans TC" 或 font-family: "Baloo Tamma 2" 了 這邊我直接單獨把 "Baloo Tamma 2" 做一個 class 來用 另外順便附上校長提供的 [Google Font 教學筆記](https://hackmd.io/@YmcMgo-NSKOqgTGAjl_5tg/ryar-vGOd/%2FbvLKze7nRU6kOa2jZxXDIg) ## 開始做 ### header 首先因為這個頭部非滿版 但是他的背景跟下面邊框都是滿版的 所以先寫一個 div 設置背景跟邊框 然後裡面再寫一個 div 給他 container 的樣式 等等的 navbar 就放在 container 裡面~ <span class="main">設計稿的頭部 navbar 直接拿 bootstrap5 的元件複製貼上改一下就好</span> (還有手機版服務 超棒XD) 所以我們來到[這裡](https://bootstrap5.hexschool.com/docs/5.0/components/navbar/) 複製貼上 再改一下字,完成 XD <span class="main">LOGO 的部分就用 navbar-brand 這個 class 來套 裡面放 LOGO 圖片</span> 設計稿有給 LOGO 寬高 可以直接寫在 img 標籤上 再來右邊有兩顆按鈕 <span class="main">登入、註冊 這個就貼兩個 button 元件 然後改一下樣式即可 按鈕貼右邊可以使用 flex end 實現</span> 然後整個 <span class="main">navbar 的下面是不是有一條 warning 色的邊框 那個請參考通用類別的邊框</span>(按鈕的圓弧效果也可以在那邊找到使用方式) 這裡我就不詳細寫了 怕你們給我複製貼上 我會被校長飛踢 XD ### 最上面主要區塊 接著往下是一個標籤、一個標題,然後左邊圖片、右邊雜七雜八東西 這裡<span class="main">用格線系統</span>,首先上面標題跟標籤的部分,我自己是直接設十二欄~ 然後<span class="main">左邊圖片佔七欄 右邊鬼東西佔五欄~</span>可以參考[這個](https://drive.google.com/file/d/1mFN6FTRijd2tT2gfFqK4Yxw9LRKWOl86/view) 這邊圖片是圓弧狀的 所以需要加上圓弧邊框不然四個角落會出現白色區塊 再來講一下雜七雜八那塊有一個<span class="main">『專案募資中!...後一百字省略』的區塊,這邊可以[參考這個](https://bootstrap5.hexschool.com/docs/5.0/customize/components/#creating-your-own)</span> 我自己是直接設 border bg-white 等等實現啦 但在嗑 bootstrap5 客製化教學影片的時候剛好看到這個(後悔莫及) 給各位拿去配~ 其他要注意的是 hover 效果,在雜七雜八那邊有<span class="main">四個小 icon 分別是 認證、品質、原生、人氣 這裏的 hover 效果請使用 [tooltips 元件](https://bootstrap5.hexschool.com/docs/5.0/components/tooltips/) 要記得加入 JS 代碼把它初始化才有正確效果~</span> ### nav&tab 的 nav 再來繼續往下是 <span class="main">nav&tab 頁籤功能~ 這裡因應設計稿我是把它做成同一頁</span>,如果同學堅持想做四頁用 href 連結也可以哩!但我不負責教學XD 首先<span class="main">用一個 div 把 nav 包起來 給 div 加上 position-sticky 讓 nav 往下滾動後可以黏在頭部~~</span> 順便也給 div 上下加邊框~~ <span class="main">這邊要請同學加一段手寫的樣式 z-index 999</span> 然後<span class="main">請自己手寫 active 的那個下底線樣式</span> 我是寫這樣 給你們參考: ```sass= .nav .active { font-weight: bold; border-bottom: 2px solid #ffc107; } ``` ### nav&tab 的 tab - 專案內容 nav 先這樣 往下來說 tab 的部分 這裏我目前只做 tab 第一個專案介紹 這邊我<span class="main">設專案介紹那區塊佔 8 欄 另外一堆逼人贊助的卡片佔 4 欄</span> 然後這裡我<span class="main">在 row 身上有設大 gutter (g-5)</span> 因為我看設計稿兩個區塊的鴻溝 48px ~ 再來講裡面內容的部分 那一堆像佛經的<span class="main">文字部分在設計稿用 justify 對齊 但 bootstrap 只有對齊左右跟置中 沒有 justify 所以這裡要去 `_utilities.scss` 改一下</span> 如下: ```sass= "text-align": ( responsive: true, property: text-align, class: text, values: ( start: left, end: right, center: center, justify: justify // 加這行 ) ), ``` 剩下應該沒啥好說的 <span class="main">圖片記得加 img-fluid ~</span> ### nav&tab 的 tab - 常見問答 這邊<span class="main">建議使用手風琴效果做 手風琴元件中有使用折疊了 會比較好做</span> 另外這邊的樣式修改部分可能要再調整一下 原本的點擊後會出現淡淡的藍色陰影跟邊框 再調整一下 設計稿只有提供第一個問題的內容 所以其他的問題的內容你們可以直接延用第一題的就好~ Q1~Q6 的黃色區塊我自己是使用標籤下去做 這邊的字體是粗體要注意一下 其他應該還好 這邊順便附上[手風琴元件的文檔](https://bootstrap5.hexschool.com/docs/5.0/components/accordion/) 建議選 flush 那個 預設沒樣式的比較好設樣式 ### nav&tab 的 tab - 目前進度 這邊是用卡片元件下去做的 左邊圖片右邊文字 文字的內容<span class="main">在手機版有其中一個段落隱藏了要記得設置 d-none d-md-block</span> 如果 more 的文字跑太上面建議可以用定位把它定在卡片最下面的地方 文字顏色也記得要改 ### nav&tab 的 tab - 留言 這邊有一個小細節 第一個元素的 <span class="main">只有本專案的贊助者才可以留言... 這個區塊他有背景色 不是純白</span> 我自己是手寫樣式加上去的~~ 留言的話我是寫 d-flex 下去做設定 沒有使用卡片元件 如果同學想使用卡片元件做也 ok 看個人~ 這邊也分享一下我的結構大致是這樣: ```htmlembedded= <div class="col-12"> <div class="border rounded p-3"> <div class="d-flex justify-content-start"> <img src="https://ecjia.com.tw/demo/bs5_homework_0526/assets/user_img01.jpg" alt="廖小杰個人頭像" /> <div class="d-flex flex-column ms-3"> <a href="#">廖小杰</a> <small class="text-secondary">2020年5月22日 11:32</small> </div> </div> <p class="my-3"> 晚上起床上廁所看到照片裡的人一直動其實有點恐怖,希望可以有暫停或是定時的功能! </p> <div class="p-3 bg-light rounded-2"> <span class="text-danger w-100 d-block mb-2">提案者回覆</span> 你要嘛起床的時候開燈,要嘛給我們更多錢開發阿 </div> </div> </div> ``` ### 最下方表單 form 下一個部分是表單~因為他也佔 8 欄 我是直接寫在 tab 的那個 8 欄裡面 <span class="main">表單一開始的 icon 手手愛心那個,用 flex 加上水平置中</span>就可以做了~這應該沒問題吧! 再來<span class="main">標題那個 贊助專案 左右加水平線那個</span>,你們給我自己搞,我<span class="main">每日任務出過了</span>!不會的我一個人圍毆你! 上面兩個東西弄完開始正式做表單 首先<span class="main">要用 form 標籤~ 在 form 標籤裡面就可以開始放 label + input </span>了~ 我們可以直接到[表單概觀](https://bootstrap5.hexschool.com/docs/5.0/forms/overview/)這邊複製範例過來~ 第一個贊助方案是 select 標籤!這邊我隨便做三個 option 分別叫 方案一二三~ 代碼大概長這樣: ```htmlembedded= <label for="project" class="form-label">贊助方案</label> <select class="form-select" id="project"> <option selected="">請選擇一個方案</option> <option value="1">方案1</option> <option value="2">方案2</option> <option value="3">方案3</option> </select> ``` <span class="main">form-* 的 class 請不要忘記加</span> 不然會導致無法對齊 畫面變得很醜~! 說明一下: <span class="main">label 的 for 屬性是用來綁定跟對齊的~ 一個 label 通常對應一個 input 或 select 並且這邊是使用 id ~</span> 這部分跟 bootstrap 無關 單純是 label 標籤的特性。 這邊記得加表單驗證!!! 主要是在 form 標籤身上加 class `.needs-validation` 然後加一個屬性 `novalidate`(取消預設的 HTML5 驗證) 再來是裡面的 input 跟 select 加上 required 屬性 表示這些欄位必填 沒填驗證會失敗出現警告這樣 最後就在表單的按鈕加上 type="submit" 然後貼上 form 表單驗證的 js 即可~ ```javascript= (function () { "use strict"; var forms = document.querySelectorAll(".needs-validation"); Array.prototype.slice.call(forms).forEach(function (form) { form.addEventListener( "submit", function (event) { if (!form.checkValidity()) { event.preventDefault(); event.stopPropagation(); } form.classList.add("was-validated"); }, false ); }); })(); ``` 然後其他沒要注意的了 下一題~ ### 下方右邊逼人贊助專案的卡片區 下一題是那個一直逼人贊助的卡片區塊~~ 說明一下 <span class="main">因為這個區塊他到時候是黏在右上角 可以滾動 且跟左邊 tab 區塊的滾動是分開的 所以要另外設置高度 overflow 跟 position</span> 另外在手機版的時候這個區塊會跑去頁籤內容跟表單的中間 這部分的話是建議直接另外複製一份放到那邊 然後使用 d-md-none 的方式讓他只在手機版顯示出來 手機版的話這個區塊不用黏在上面也不用滾動 所以不需要設置高度、 overflow 跟 position 首先這邊是一個 col-5 然後裡面先給一個 div 這個 div 給他設高度 讓他高度為螢幕高減去 nav 的高度 這邊可以使用 `calc(100vh - xxx)` calc() 方法是 CSS3 出的 它可以用來加減乘除各種不同單位的數字 要記得在運算符號左右留空白 如果你沒留空白就無法計算會報錯~然後 100vh 是指螢幕高度 100% ~設完高度後給他加上 overflow-auto 讓他超過高度的地方可以滾動~ 然後再給他加上 position-sticky 把它黏在 nav 的下面~這裡可能也是需要手寫計算 top 設多少~~ 再來就可以直接在 div 裡面加入卡片元件了~基本上也沒啥大問題好說,圖片圓形的部分也是參考通用類別的邊框即可找到~ 然後<span class="main">第一個卡片缺錢事務所裡面的 icon 是用 font-awesome ~ 這邊需要自己手寫樣式</span>設定一個圓形的背景 gray 的區塊放 icon 才有辦法達到設計稿的效果~ 給你們看我的代碼: ```htmlembedded= <div class="bg-secondary rounded-circle text-center me-2" style="width: 30px;height: 30px;"> <i class="fab fa-facebook-f text-white lh-lg"></i> </div> ``` ### footer ok 最後就我們的 footer 了 <span class="main">背景色跟 $body-color 是同色的~</span>啊這邊要注意一下,我不知道你們有沒有遇到這個問題,就是<span class="main">在設計稿點擊文字可以複製內容</span>,但我點擊 footer 的那行字 複製後都長這樣: Copyright � 拼拼 All rights reserved. 所以貼心的 me 手動幫你們補一下: ``` Copyright © 拼拼 All rights reserved. ``` 以上,沒問題的話可以開始照著筆記做啦~ 有問題請在 slack 上 tag 我或私訊我哩!謝謝收看:D ## 給新手的每日任務參考方向 ### 5/31 每日任務解析 1. navbar 可以使用 [元件導覽列](https://bootstrap5.hexschool.com/docs/5.0/components/navbar/) + [元件互動視窗](https://bootstrap5.hexschool.com/docs/5.0/components/modal/) + [通用類別邊框](https://bootstrap5.hexschool.com/docs/5.0/utilities/borders/) 完成 2. 在找導覽列(navbar)範例時請找含有手機版的~(有看到帶有 navbar-toggler 樣式的就表示它有手機版) 3. 另外 LOGO 部分可以使用 navbar-brand 這個 class 裡面放 img 標籤 4. 在 img 標籤上可以直接寫 width height 屬性設定圖片大小 5. 按鈕圓弧效果的部分可以在[通用類別邊框](https://bootstrap5.hexschool.com/docs/5.0/utilities/borders/)找到 6. 登入 modal 的上方有邊框 要記得添加 7. 登入 modal 的內容表單部分可以使用[表單概觀](https://bootstrap5.hexschool.com/docs/5.0/forms/overview/)第一個範例 8. 登入 modal 的登入按鈕寬度 100% 可參考[通用類別尺寸](https://bootstrap5.hexschool.com/docs/5.0/utilities/sizing/) 9. 登入 modal 的 還沒有帳號?註冊一個帳號 文字左右加水平線請參考[通用類別位置](https://bootstrap5.hexschool.com/docs/5.0/utilities/position/) 與之前 [🗞 5/27(四) 每日任務](/@WangShuan/rkmyTmttO) ### 6/1 每日任務解析 1. 這裡需要用[排版網格系統](https://bootstrap5.hexschool.com/docs/5.0/layout/grid/)分區塊 2. 標題跟標籤的區塊建議設置十二欄 標籤的部分可以使用[元件標籤](https://bootstrap5.hexschool.com/docs/5.0/components/badge/) 3. 下方圖片區塊佔七欄 另外五欄先留白(週五製作,那邊比較複雜一點) 4. 請記得製作手機版 佔十二欄 5. 這邊記得加上 img-fluid 讓圖片自適應,因為原圖很大會破版~ 6. 另外圖片的部分四個角是圓弧 需要加上邊框圓弧效果不然會出現白色區塊 7. 該區塊的背景不是白色 請記得添加處理背景色~可參考[通用類別Background](https://bootstrap5.hexschool.com/docs/5.0/utilities/background/) ### 6/2 每日任務解析 1. 上面的 nav 的部分之前做過類似的 所以這裡直接跳過,不知道的可以回顧 [🗞 5/26(三) 每日任務](/abj9pHlfQPKSwgS-tc12_g) [🗞 5/28(五) 每日任務](/@WangShuan/r1seBIYKu) 的每日任務 記得加線條與 active 樣式 2. 請設計一個 row 其 gutter 為 48px 可參考[排版Gutters](https://bootstrap5.hexschool.com/docs/5.0/layout/gutters/) 3. 這個區塊是 col-8 的區塊 (另外 col-4 區塊後面做) 4. 請記得做手機版 手機版時佔十二欄 ### 6/3 每日任務解析 1. 該表單區塊佔據 8 欄,最上方的 icon 可以參考[通用類別 flex](https://bootstrap5.hexschool.com/docs/5.0/utilities/flex/) 使用水平置中對齊完成 2. 贊助專案的標題左右加水平線部分 請參考[通用類別位置](https://bootstrap5.hexschool.com/docs/5.0/utilities/position/) 與之前 [5/27 每日任務](https://hackmd.io/@WangShuan/rkmyTmttO) 3. 表單裡面的內容自行參考[表單概觀](https://bootstrap5.hexschool.com/docs/5.0/forms/overview/) 4. 請注意手機版時最下方的按鈕寬度為 100% 另外手機版時佔十二欄 ### 6/4 每日任務解析 1. 手機版時這個區塊佔據十二欄 手機版與電腦版的差異還請自行研究設計稿處理 2. 除了日期與時間的地方 其他數字是使用 Baloo Tamma 2 的字型 要記得處理 3. 目標$600,000 vs $280,047 有使用到絕對定位 請參考[通用類別位置](https://bootstrap5.hexschool.com/docs/5.0/utilities/position/) 4. 1374 人、 27天 跟上面的小字 贊助人數、募資倒數 也有用到絕對定位 請參考[通用類別位置](https://bootstrap5.hexschool.com/docs/5.0/utilities/position/) 5. 1374 人、 27天 人跟天的文字與數字的文字記得要做區分 大小與字型都有不同 6. 四個小 icon 有 hover 效果,需使用元件工具提示框完成(hover 時的文字可以看手機版的這個區塊找到) 7. 最下面的按鈕 hover 效果可以先嘗試用 important 添加看看(這邊如果真做不出來就等上完 SCSS 客製化教學再做) 8. 按鈕的 icon 使用 font-awesome 記得引入 ### 6/7 每日任務解析 1. 邊框圓弧效果跟圖片圓形效果請參考[這個](https://bootstrap5.hexschool.com/docs/5.0/utilities/borders/) 2. 缺錢事務所的區塊可以使用[卡片元件](https://bootstrap5.hexschool.com/docs/5.0/components/card/)也可以直接用 flex 做,我自己是沒有用卡片元件~ 3. 發起 1 個專案的 1 字體有單獨加粗 請注意。 4. 裡面的 fb 跟 youtube 是用 font-awesome 引入的 iocn , fb 跟 youtube 的背景跟小圓圈的部分要自己寫樣式~ 5. 下方的 選擇方案支持 區塊有圓弧效果 邊框只有左右 然後他的背景不是白色哦!記得給他正確背景色。 6. 手機版時有文字隱藏了記得處理~~ 可參考[display](https://bootstrap5.hexschool.com/docs/5.0/utilities/display/)的部分。 ### 6/8 每日任務解析 1. 這邊手機版看起來是沒有更動,好像只需把它改成 12 欄~ 2. 做這個的話建議是直接用[卡片元件](https://bootstrap5.hexschool.com/docs/5.0/components/card/)~ 3. NT$ 1600 的字體是 Baloo Tamma 2 4. 限時優惠下方那條線請不要用 hr 標籤,使用 border 就好 5. 88次 200個的數字不是 Baloo Tamma 2 不要改~只需要改 200 的顏色即可 6. 贊助此專案的按鈕 hover 記得做~ <font color="#7952b3">最後感謝大家報名實戰營的活動~恭喜畢業~🎉</font> ## JS 代碼部分 ### 點擊 nav 切換頁籤時滾到 tab 區塊效果 請在每個 nav 的 li 的 a 連結身上加這個 `onclick="goToTab()"` 然後在 body 標籤最下面加上新的 `script` 標籤 並將下面代碼加入到 `script` 標籤中: ```javascript= function heightToTop(ele) { let bridge = ele; let root = document.body; let height = 0; do { height += bridge.offsetTop; bridge = bridge.offsetParent; } while (bridge !== root); return height; } function goToTab() { window.scrollTo({ top: heightToTop(document.getElementsByClassName("tab-content")[0]) - 70, behavior: "smooth", }); } ``` ### 手機版點擊按鈕滾到表單區塊效果 請先在手機版新增一個贊助專案按鈕 寬度 100% 並取消圓角 然後給該按鈕加上 `id="bottomBtn" onclick="goForm()"` 再給表單加上 `id="form"` 然後在剛才的 script 標籤加入以下代碼: ```javascript= function goForm() { window.scrollTo({ top: heightToTop(form) - 170, behavior: "smooth", }); } var bottomBtn = document.getElementById("bottomBtn"); bottomBtn.style.display = "none"; window.onscroll = function () { const t = document.documentElement.scrollTop || document.body.scrollTop; if (bottomBtn !== null) { if ( t > heightToTop(document.getElementsByClassName("tab-content")[0]) - 100 && t < heightToTop(form) ) { bottomBtn.style.display = "block"; } else { bottomBtn.style.display = "none"; } } }; ``` ### 最終 script 標籤中所有 JS 代碼 正常情況下會用到表單驗證跟工具提示 再加上面兩段 JS 完成後應該會有這些代碼: ```javascript= // enable tooltips var tooltipTriggerList = [].slice.call( document.querySelectorAll('[data-bs-toggle="tooltip"]') ); var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { return new bootstrap.Tooltip(tooltipTriggerEl); }); // click nav&tab go there & click go to form var form = document.getElementById("form"); function heightToTop(ele) { let bridge = ele; let root = document.body; let height = 0; do { height += bridge.offsetTop; bridge = bridge.offsetParent; } while (bridge !== root); return height; } function goToTab() { window.scrollTo({ top: heightToTop(document.getElementsByClassName("tab-content")[0]) - 70, behavior: "smooth" }); } function goForm() { window.scrollTo({ top: heightToTop(form) - 170, behavior: "smooth" }); } // mobile btn toggle var bottomBtn = document.getElementById("bottomBtn"); bottomBtn.style.display = "none"; window.onscroll = function () { const t = document.documentElement.scrollTop || document.body.scrollTop; if (bottomBtn !== null) { if ( t > heightToTop(document.getElementsByClassName("tab-content")[0]) - 100 && t < heightToTop(form) ) { bottomBtn.style.display = "block"; } else { bottomBtn.style.display = "none"; } } }; // form validation (function () { "use strict"; var forms = document.querySelectorAll(".needs-validation"); Array.prototype.slice.call(forms).forEach(function (form) { form.addEventListener( "submit", function (event) { if (!form.checkValidity()) { event.preventDefault(); event.stopPropagation(); } form.classList.add("was-validated"); }, false ); }); })(); ```