課程學習:六角學院
CH9 – 使用 Bootstrap 完成 Blog 版型
Blog 版型 – 簡介
// index.html - Blog 版型 - 簡介
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog Live</title>
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style>
:root {
--bs-font-sans-serif: system-ui,-apple-system,'Microsoft JhengHei',微軟正黑體,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
}
</style>
</head>
<body>
這裡是一段文字
</body>
</html>
Blog 版型 – 導覽列
// index.html - Blog 版型 - 導覽列
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog Live</title>
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style>
:root {
--bs-font-sans-serif: system-ui,-apple-system,'Microsoft JhengHei',微軟正黑體,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
}
</style>
</head>
<body>
<div class="container">
<header class="py-3 text-center border-bottom">
<a href="#" class="h2 link-dark text-decoration-none">Gee Hsu 的 Blog</a>
</header>
<div class="overflow-auto py-1">
<nav class="nav justify-content-between flex-nowrap text-nowrap">
<a href="#" class="nav-link link-secondary">HTML</a>
<a href="#" class="nav-link link-secondary">CSS</a>
<a href="#" class="nav-link link-secondary">jQuery</a>
<a href="#" class="nav-link link-secondary">JavaScript</a>
<a href="#" class="nav-link link-secondary">RWD</a>
<a href="#" class="nav-link link-secondary">Bootstrap</a>
<a href="#" class="nav-link link-secondary">Vue</a>
<a href="#" class="nav-link link-secondary">Git&GitHub</a>
<a href="#" class="nav-link link-secondary">NodeJs</a>
<a href="#" class="nav-link link-secondary">Adobe XD</a>
<a href="#" class="nav-link link-secondary">Sass</a>
<a href="#" class="nav-link link-secondary">VSCode</a>
</nav>
</div>
</div>
</body>
</html>
垂直圈選:
Mac: option + 左鍵
Windows: 滑鼠中鍵
Blog 版型 – 首圖背景
// index.html - Blog 版型 - 首圖背景
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog Live</title>
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style>
:root {
--bs-font-sans-serif: system-ui,-apple-system,'Microsoft JhengHei',微軟正黑體,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
}
.bg-cover {
background-position: center center;
background-size: cover;
}
</style>
</head>
<body>
<div class="container">
<header class="py-3 text-center border-bottom">
<a href="#" class="h2 link-dark text-decoration-none">Gee Hsu 的 Blog</a>
</header>
<!-- Blog 版型 - 導覽列 start -->
<div class="overflow-auto py-1">
<nav class="nav justify-content-between flex-nowrap text-nowrap">
<a href="#" class="nav-link link-secondary">HTML</a>
<a href="#" class="nav-link link-secondary">CSS</a>
<a href="#" class="nav-link link-secondary">jQuery</a>
<a href="#" class="nav-link link-secondary">JavaScript</a>
<a href="#" class="nav-link link-secondary">RWD</a>
<a href="#" class="nav-link link-secondary">Bootstrap</a>
<a href="#" class="nav-link link-secondary">Vue</a>
<a href="#" class="nav-link link-secondary">Git&GitHub</a>
<a href="#" class="nav-link link-secondary">NodeJs</a>
<a href="#" class="nav-link link-secondary">Adobe XD</a>
<a href="#" class="nav-link link-secondary">Sass</a>
<a href="#" class="nav-link link-secondary">VSCode</a>
</nav>
</div>
<!-- Blog 版型 - 導覽列 end -->
<!-- Blog 版型 - 首圖背景 start -->
<div class="p-4 p-md-5 text-white rounded-3 bg-cover" style="background-image: url(https://images.unsplash.com/photo-1545641203-7d072a14e3b2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1033&q=80);">
<div class="col-md-6">
<h1 class="display-4 fst-italic">雨水經由高山地形匯流成溪河</h1>
<p class="lead my-3">一個河流需要時間的積累才能形成,知識的累積也是從少到多。</p>
<p class="lead mb-0"><a class="text-white" href="#">繼續閱讀</a></p>
</div>
</div>
<!-- Blog 版型 - 首圖背景 end -->
</div>
</body>
</html>
Blog 版型 – 水平卡片排版技巧
這個地方算是這個網站配置最為複雜。
// index.html - Blog 版型 - 水平卡片排版技巧
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog Live</title>
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style>
:root {
--bs-font-sans-serif: system-ui,-apple-system,'Microsoft JhengHei',微軟正黑體,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
}
.bg-cover {
background-position: center center;
background-size: cover;
}
</style>
</head>
<body>
<div class="container">
<header class="py-3 text-center border-bottom">
<a href="#" class="h2 link-dark text-decoration-none">Gee Hsu 的 Blog</a>
</header>
<!-- Blog 版型 - 導覽列 start -->
<div class="overflow-auto py-1">
<nav class="nav justify-content-between flex-nowrap text-nowrap">
<a href="#" class="nav-link link-secondary">HTML</a>
<a href="#" class="nav-link link-secondary">CSS</a>
<a href="#" class="nav-link link-secondary">jQuery</a>
<a href="#" class="nav-link link-secondary">JavaScript</a>
<a href="#" class="nav-link link-secondary">RWD</a>
<a href="#" class="nav-link link-secondary">Bootstrap</a>
<a href="#" class="nav-link link-secondary">Vue</a>
<a href="#" class="nav-link link-secondary">Git&GitHub</a>
<a href="#" class="nav-link link-secondary">NodeJs</a>
<a href="#" class="nav-link link-secondary">Adobe XD</a>
<a href="#" class="nav-link link-secondary">Sass</a>
<a href="#" class="nav-link link-secondary">VSCode</a>
</nav>
</div>
<!-- Blog 版型 - 導覽列 end -->
<!-- Blog 版型 - 首圖背景 start -->
<div class="p-4 p-md-5 mb-4 text-white rounded-3 bg-cover" style="background-image: url(https://images.unsplash.com/photo-1545641203-7d072a14e3b2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1033&q=80);">
<div class="col-md-6">
<h1 class="display-4 fst-italic">雨水經由高山地形匯流成溪河</h1>
<p class="lead my-3">一個河流需要時間的積累才能形成,知識的累積也是從少到多。</p>
<p class="lead mb-0"><a class="text-white" href="#">繼續閱讀</a></p>
</div>
</div>
<!-- Blog 版型 - 首圖背景 end -->
<!-- Blog 版型 - 水平卡片排版技巧 start -->
<div class="row row-cols-1 row-cols-lg-2">
<div class="col">
<div class="card row g-0 flex-row h-100">
<div class="col">
<div class="p-4 d-flex flex-column h-100">
<strong class="d-inline-block mb-2 text-primary">Bootstrap</strong>
<h3 class="mb-0">Blog 版型</h3>
<div class="mb-1 text-muted">三月 7 日</div>
<p class="card-text mb-auto">使用 Bootstrap 完成 Blog 版型。</p>
<a href="#" class="stretched-link">繼續閱讀</a>
</div>
</div>
<div class="col-4 d-none d-lg-block bg-cover" style="background-image: url(https://images.unsplash.com/photo-1600656801344-b1ec70d4058d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80);"></div>
</div>
</div>
<div class="col">
<div class="card row g-0 flex-row h-100">
<div class="col">
<div class="p-4">
<strong class="d-inline-block mb-2 text-primary">Bootstrap</strong>
<h3 class="mb-0">Blog 版型</h3>
<div class="mb-1 text-muted">三月 7 日</div>
<p class="card-text mb-auto">使用 Bootstrap 完成 Blog 版型。學習的內容有:Blog 版型 - 簡介、Blog 版型 - 導覽列、Blog 版型 - 首圖背景...等</p>
<a href="#" class="stretched-link">繼續閱讀</a>
</div>
</div>
<div class="col-4 d-none d-lg-block bg-cover" style="background-image: url(https://images.unsplash.com/photo-1600656801344-b1ec70d4058d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80);"></div>
</div>
</div>
</div>
<!-- Blog 版型 - 水平卡片排版技巧 end -->
</div>
</body>
</html>
Blog 版型 – 內文及側欄安排
// index.html - Blog 版型 - 內文及側欄安排
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog Live</title>
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style>
:root {
--bs-font-sans-serif: system-ui,-apple-system,'Microsoft JhengHei',微軟正黑體,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
}
.bg-cover {
background-position: center center;
background-size: cover;
}
</style>
</head>
<body>
<div class="container">
<header class="py-3 text-center border-bottom">
<a href="#" class="h2 link-dark text-decoration-none">Gee Hsu 的 Blog</a>
</header>
<!-- Blog 版型 - 導覽列 start -->
<div class="overflow-auto py-1">
<nav class="nav justify-content-between flex-nowrap text-nowrap">
<a href="#" class="nav-link link-secondary">HTML</a>
<a href="#" class="nav-link link-secondary">CSS</a>
<a href="#" class="nav-link link-secondary">jQuery</a>
<a href="#" class="nav-link link-secondary">JavaScript</a>
<a href="#" class="nav-link link-secondary">RWD</a>
<a href="#" class="nav-link link-secondary">Bootstrap</a>
<a href="#" class="nav-link link-secondary">Vue</a>
<a href="#" class="nav-link link-secondary">Git&GitHub</a>
<a href="#" class="nav-link link-secondary">NodeJs</a>
<a href="#" class="nav-link link-secondary">Adobe XD</a>
<a href="#" class="nav-link link-secondary">Sass</a>
<a href="#" class="nav-link link-secondary">VSCode</a>
</nav>
</div>
<!-- Blog 版型 - 導覽列 end -->
<!-- Blog 版型 - 首圖背景 start -->
<div class="p-4 p-md-5 mb-4 text-white rounded-3 bg-cover" style="background-image: url(https://images.unsplash.com/photo-1545641203-7d072a14e3b2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1033&q=80);">
<div class="col-md-6">
<h1 class="display-4 fst-italic">雨水經由高山地形匯流成溪河</h1>
<p class="lead my-3">一個河流需要時間的積累才能形成,知識的累積也是從少到多。</p>
<p class="lead mb-0"><a class="text-white" href="#">繼續閱讀</a></p>
</div>
</div>
<!-- Blog 版型 - 首圖背景 end -->
<!-- Blog 版型 - 水平卡片排版技巧 start -->
<div class="row row-cols-1 row-cols-lg-2 mb-5">
<div class="col">
<div class="card row g-0 flex-row h-100">
<div class="col">
<div class="p-4 d-flex flex-column h-100">
<strong class="d-inline-block mb-2 text-primary">Bootstrap</strong>
<h3 class="mb-0">Blog 版型</h3>
<div class="mb-1 text-muted">三月 7 日</div>
<p class="card-text mb-auto">使用 Bootstrap 完成 Blog 版型。</p>
<a href="#" class="stretched-link">繼續閱讀</a>
</div>
</div>
<div class="col-4 d-none d-lg-block bg-cover" style="background-image: url(https://images.unsplash.com/photo-1600656801344-b1ec70d4058d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80);"></div>
</div>
</div>
<div class="col">
<div class="card row g-0 flex-row h-100">
<div class="col">
<div class="p-4">
<strong class="d-inline-block mb-2 text-primary">Bootstrap</strong>
<h3 class="mb-0">Blog 版型</h3>
<div class="mb-1 text-muted">三月 7 日</div>
<p class="card-text mb-auto">使用 Bootstrap 完成 Blog 版型。學習的內容有:Blog 版型 - 簡介、Blog 版型 - 導覽列、Blog 版型 - 首圖背景...等</p>
<a href="#" class="stretched-link">繼續閱讀</a>
</div>
</div>
<div class="col-4 d-none d-lg-block bg-cover" style="background-image: url(https://images.unsplash.com/photo-1600656801344-b1ec70d4058d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80);"></div>
</div>
</div>
</div>
<!-- Blog 版型 - 水平卡片排版技巧 end -->
<!-- Blog 版型 - 內文及側欄安排 start -->
<div class="row g-md-5">
<div class="col-md-8">
<article>
<h2>使用 Bootstrap 完成 Blog 版型</h2>
<p>2022 年三月 <a href="#">Gee Hsu</a></p>
<p><img class="img-fluid" src="https://firebasestorage.googleapis.com/v0/b/hexschool-api.appspot.com/o/blog%2F2021%2F10%2F25%2Fog.png?alt=media&token=787ab669-10c4-4456-b8d1-9354814a43d4" alt=""></p>
<p>文章擷取來自卡斯柏老師~</p>
<p>請問你切版時,是用哪一個方式在進行呢?</p>
<ul>
<li>手刻至上,不使用框架或任何工具</li>
<li>使用 Sass 等工具,透過相關方法優化結構</li>
<li>使用框架作為基底,並自行撰寫 CSS 調整樣式</li>
<li>使用框架搭配 Sass 進行整合,大幅加速開發速度</li>
</ul>
<h2 id="從純-CSS-轉至工具至上的開發型態"><a href="#從純-CSS-轉至工具至上的開發型態" class="headerlink" title="從純 CSS 轉至工具至上的開發型態"></a>從純 CSS 轉至工具至上的開發型態</h2><p>過去,我也是使用純 CSS 的方式在撰寫網頁,不過隨著工具越來越豐富,我也從純 CSS 慢慢轉變為 Sass 及 Bootstrap 整合的方式進行開發,明顯的差異點在於:</p>
<ul>
<li><b>CSS 行數大幅減少</b>:以前動輒上千行的 CSS,現在只需要調整變數就能完成,可以專注在新功能的開發</li>
<li><b>協作更為容易</b>:每個人撰寫的習慣不同,就如 “按鈕” 有人習慣稱為 <code>button</code> 有些人則習慣使用 <code>btn</code> ,甚至同一個人每個階段的撰寫方式都不一樣。透過框架命名、架構的習慣會更有一致性。</li>
<li><b>不需要每次撰寫相同的模組</b>:同樣的按鈕每個網站都需要用到,如果每次都重新撰寫將會花去不少時間,就算是 copy & paste 都有可能出錯,與其如此不如就直接引入,快速又可減少錯誤~</li>
</ul>
<p>許多細微的差異下,從過去一個網站需花費兩週,到現在只需要 1 ~ 2 天就可完成相同品質的網站,剩下的時間可以用來優化更進階的視覺效果,長時間累積下來自然能夠有超越其他人的表現。</p>
<p>來自一段學長姐的話:<br>
</p><p class="border-left border-dark pl-3">切版一定要快,如果連 CSS 都搞不定怎麼能做好專業的前端工程師呢?</p>
<p></p>
<img class="img-fluid" src="https://firebasestorage.googleapis.com/v0/b/hexschool-api.appspot.com/o/blog%2F2021%2F10%2F25%2Fblock.jpg?alt=media&token=5bbcb44d-3982-4128-9452-6309c31c23b9" class="mx-auto" style="width: 60%">
<h2 id="Bootstrap-5-網頁開發整合術"><a href="#Bootstrap-5-網頁開發整合術" class="headerlink" title="Bootstrap 5 網頁開發整合術"></a>Bootstrap 5 網頁開發整合術</h2><ul>
<li>聽說 Bootstrap 都長一樣,怎麼可能符合每個網站的需求?<br>→ 實戰都會透過變數客製化,調整成符合每個網站樣式及需求啦</li>
<li>Sass 環境好像很難搞,學的時間該不會就抵掉之後節省的時間?<br>→ 課程中只花 3 分鐘介紹如何安裝 Sass 環境,只要文字編輯器不須另外安裝工具,相信你用一次就上癮</li>
<li>上述介紹了 Bootstrap 5 的一些特點,但這個工具真的有這麼好嗎?<br>→ 來參加活動,我現場示範給你看</li>
</ul>
<p>接下來,我們預計在 10/27 進行「 Bootstrap 5 網頁開發整合術」的課程介紹,歡迎你提前發問,我將在直播過程中一一回覆。</p>
</article>
</div>
<div class="col-md-4 d-none d-md-block">
<div class="sticky-top" style="top: 16px;">
<div class="p-4 bg-light rounded">
<h4>關於我</h4>
<p class="mb-0">學習製作網站,關於網頁開發相關技巧。<br>開發技巧有:HTML、CSS、JAVASCRIPT、JQUERY、RWD、BOOTSTRAP、VUE、GIT&GITHUB...等相關技巧。</p>
</div>
<div class="p-4">
<h4>封存</h4>
<ol class="list-unstyled">
<li><a href="#">2022年 三月</a></li>
<li><a href="#">2022年 二月</a></li>
<li><a href="#">2022年 一月</a></li>
<li><a href="#">2021年 十二月</a></li>
<li><a href="#">2021年 十一月</a></li>
<li><a href="#">2021年 月</a></li>
<li><a href="#">2021年 月</a></li>
<li><a href="#">2021年 月</a></li>
<li><a href="#">2021年 月</a></li>
<li><a href="#">2021年 月</a></li>
</ol>
</div>
<div class="p-4">
<h4>追蹤我</h4>
<ul class="list-unstyled">
<li><a href="#">Github</a></li>
<li><a href="#">Facebook</a></li>
<li><a href="#">Twitter</a></li>
</ul>
</div>
</div>
</div>
</div>
<!-- Blog 版型 - 內文及側欄安排 end -->
</div>
</body>
</html>
Blog 版型 – Footer 製作
// index.html - Blog 版型 - Footer 製作
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog Live</title>
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style>
:root {
--bs-font-sans-serif: system-ui,-apple-system,'Microsoft JhengHei',微軟正黑體,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
}
.bg-cover {
background-position: center center;
background-size: cover;
}
</style>
</head>
<body>
<div class="container">
<header class="py-3 text-center border-bottom">
<a href="#" class="h2 link-dark text-decoration-none">Gee Hsu 的 Blog</a>
</header>
<!-- Blog 版型 - 導覽列 start -->
<div class="overflow-auto py-1">
<nav class="nav justify-content-between flex-nowrap text-nowrap">
<a href="#" class="nav-link link-secondary">HTML</a>
<a href="#" class="nav-link link-secondary">CSS</a>
<a href="#" class="nav-link link-secondary">jQuery</a>
<a href="#" class="nav-link link-secondary">JavaScript</a>
<a href="#" class="nav-link link-secondary">RWD</a>
<a href="#" class="nav-link link-secondary">Bootstrap</a>
<a href="#" class="nav-link link-secondary">Vue</a>
<a href="#" class="nav-link link-secondary">Git&GitHub</a>
<a href="#" class="nav-link link-secondary">NodeJs</a>
<a href="#" class="nav-link link-secondary">Adobe XD</a>
<a href="#" class="nav-link link-secondary">Sass</a>
<a href="#" class="nav-link link-secondary">VSCode</a>
</nav>
</div>
<!-- Blog 版型 - 導覽列 end -->
<!-- Blog 版型 - 首圖背景 start -->
<div class="p-4 p-md-5 mb-4 text-white rounded-3 bg-cover" style="background-image: url(https://images.unsplash.com/photo-1545641203-7d072a14e3b2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1033&q=80);">
<div class="col-md-6">
<h1 class="display-4 fst-italic">雨水經由高山地形匯流成溪河</h1>
<p class="lead my-3">一個河流需要時間的積累才能形成,知識的累積也是從少到多。</p>
<p class="lead mb-0"><a class="text-white" href="#">繼續閱讀</a></p>
</div>
</div>
<!-- Blog 版型 - 首圖背景 end -->
<!-- Blog 版型 - 水平卡片排版技巧 start -->
<div class="row row-cols-1 row-cols-lg-2 mb-5">
<div class="col">
<div class="card row g-0 flex-row h-100">
<div class="col">
<div class="p-4 d-flex flex-column h-100">
<strong class="d-inline-block mb-2 text-primary">Bootstrap</strong>
<h3 class="mb-0">Blog 版型</h3>
<div class="mb-1 text-muted">三月 7 日</div>
<p class="card-text mb-auto">使用 Bootstrap 完成 Blog 版型。</p>
<a href="#" class="stretched-link">繼續閱讀</a>
</div>
</div>
<div class="col-4 d-none d-lg-block bg-cover" style="background-image: url(https://images.unsplash.com/photo-1600656801344-b1ec70d4058d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80);"></div>
</div>
</div>
<div class="col">
<div class="card row g-0 flex-row h-100">
<div class="col">
<div class="p-4">
<strong class="d-inline-block mb-2 text-primary">Bootstrap</strong>
<h3 class="mb-0">Blog 版型</h3>
<div class="mb-1 text-muted">三月 7 日</div>
<p class="card-text mb-auto">使用 Bootstrap 完成 Blog 版型。學習的內容有:Blog 版型 - 簡介、Blog 版型 - 導覽列、Blog 版型 - 首圖背景...等</p>
<a href="#" class="stretched-link">繼續閱讀</a>
</div>
</div>
<div class="col-4 d-none d-lg-block bg-cover" style="background-image: url(https://images.unsplash.com/photo-1600656801344-b1ec70d4058d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80);"></div>
</div>
</div>
</div>
<!-- Blog 版型 - 水平卡片排版技巧 end -->
<!-- Blog 版型 - 內文及側欄安排 start -->
<div class="row g-md-5">
<div class="col-md-8">
<article>
<h2>使用 Bootstrap 完成 Blog 版型</h2>
<p>2022 年三月 <a href="#">Gee Hsu</a></p>
<p><img class="img-fluid" src="https://firebasestorage.googleapis.com/v0/b/hexschool-api.appspot.com/o/blog%2F2021%2F10%2F25%2Fog.png?alt=media&token=787ab669-10c4-4456-b8d1-9354814a43d4" alt=""></p>
<p>文章擷取來自卡斯柏老師~</p>
<p>請問你切版時,是用哪一個方式在進行呢?</p>
<ul>
<li>手刻至上,不使用框架或任何工具</li>
<li>使用 Sass 等工具,透過相關方法優化結構</li>
<li>使用框架作為基底,並自行撰寫 CSS 調整樣式</li>
<li>使用框架搭配 Sass 進行整合,大幅加速開發速度</li>
</ul>
<h2 class="mb-2"><a href="#" title="從純 CSS 轉至工具至上的開發型態"></a>從純 CSS 轉至工具至上的開發型態</h2>
<p>過去,我也是使用純 CSS 的方式在撰寫網頁,不過隨著工具越來越豐富,我也從純 CSS 慢慢轉變為 Sass 及 Bootstrap 整合的方式進行開發,明顯的差異點在於:</p>
<ul>
<li><b>CSS 行數大幅減少</b>:以前動輒上千行的 CSS,現在只需要調整變數就能完成,可以專注在新功能的開發</li>
<li><b>協作更為容易</b>:每個人撰寫的習慣不同,就如 “按鈕” 有人習慣稱為 <code>button</code> 有些人則習慣使用 <code>btn</code> ,甚至同一個人每個階段的撰寫方式都不一樣。透過框架命名、架構的習慣會更有一致性。</li>
<li><b>不需要每次撰寫相同的模組</b>:同樣的按鈕每個網站都需要用到,如果每次都重新撰寫將會花去不少時間,就算是 copy & paste 都有可能出錯,與其如此不如就直接引入,快速又可減少錯誤~</li>
</ul>
<p>許多細微的差異下,從過去一個網站需花費兩週,到現在只需要 1 ~ 2 天就可完成相同品質的網站,剩下的時間可以用來優化更進階的視覺效果,長時間累積下來自然能夠有超越其他人的表現。</p>
<p>來自一段學長姐的話:<br></p>
<p class="border-left border-dark pl-3">切版一定要快,如果連 CSS 都搞不定怎麼能做好專業的前端工程師呢?</p>
<img class="img-fluid mx-auto d-block mb-3" src="https://firebasestorage.googleapis.com/v0/b/hexschool-api.appspot.com/o/blog%2F2021%2F10%2F25%2Fblock.jpg?alt=media&token=5bbcb44d-3982-4128-9452-6309c31c23b9" style="width: 60%">
<h2 class="mb-2"><a href="#" title="Bootstrap 5 網頁開發整合術"></a>Bootstrap 5 網頁開發整合術</h2>
<ul>
<li>聽說 Bootstrap 都長一樣,怎麼可能符合每個網站的需求?<br>→ 實戰都會透過變數客製化,調整成符合每個網站樣式及需求啦</li>
<li>Sass 環境好像很難搞,學的時間該不會就抵掉之後節省的時間?<br>→ 課程中只花 3 分鐘介紹如何安裝 Sass 環境,只要文字編輯器不須另外安裝工具,相信你用一次就上癮</li>
<li>上述介紹了 Bootstrap 5 的一些特點,但這個工具真的有這麼好嗎?<br>→ 來參加活動,我現場示範給你看</li>
</ul>
<p>接下來,我們預計在 10/27 進行「 Bootstrap 5 網頁開發整合術」的課程介紹,歡迎你提前發問,我將在直播過程中一一回覆。</p>
</article>
</div>
<div class="col-md-4 d-none d-md-block">
<div class="sticky-top" style="top: 16px;">
<div class="p-4 bg-light rounded">
<h4>關於我</h4>
<p class="mb-0">學習製作網站,關於網頁開發相關技巧。<br>開發技巧有:HTML、CSS、JAVASCRIPT、JQUERY、RWD、BOOTSTRAP、VUE、GIT&GITHUB...等相關技巧。</p>
</div>
<div class="p-4">
<h4>封存</h4>
<ol class="list-unstyled">
<li><a href="#">2022年 三月</a></li>
<li><a href="#">2022年 二月</a></li>
<li><a href="#">2022年 一月</a></li>
<li><a href="#">2021年 十二月</a></li>
<li><a href="#">2021年 十一月</a></li>
<li><a href="#">2021年 十月</a></li>
<li><a href="#">2021年 九月</a></li>
<li><a href="#">2021年 八月</a></li>
<li><a href="#">2021年 七月</a></li>
<li><a href="#">2021年 六月</a></li>
</ol>
</div>
<div class="p-4">
<h4>追蹤我</h4>
<ul class="list-unstyled">
<li><a href="#">Github</a></li>
<li><a href="#">Facebook</a></li>
<li><a href="#">Twitter</a></li>
</ul>
</div>
</div>
</div>
</div>
<!-- Blog 版型 - 內文及側欄安排 end -->
</div>
<!-- Blog 版型 - Footer 製作 start -->
<footer class="bg-light border-top py-4 mt-5 text-center">
<p>Bootstrap 5 練習作業</p>
<p>
<a href="#">Back to top</a>
</p>
</footer>
<!-- Blog 版型 - Footer 製作 end -->
</body>
</html>
Blog 版型 – 作業說明
Blog 版型 – 作業範例下載
注意:
- 此檔案僅用來參考,請勿複製程式碼
CH10 – Bootstrap 與神奇的 Sass
Bootstrap 與 Sass 的關係
CSS 預處理器
以 SASS 為主的說明。
Bootstrap 就是使用 Sass 預處理器開發的喔。
什麼是預處理器?
以 Bootstrap 來說這麼大的框架原始碼檔案會是由許多小元件組成。
但是這個別的檔案並無法被瀏覽器所解析,透過 Sass 編譯器能夠將這些小元件組成完整的 CSS,並且能夠在瀏覽器上運行。
.scss 與 .sass 差在哪裡?
// .sass
.btn
display: inline-block
font-weight: $btn-font-weight
text-align: center
+transition($btn-transition}
.sass
是原始的 sass 格式,特點是沒有花括號及分號,讓程式碼呈現極簡的風格。
// .scss
.btn {
display: inline-block;
font-weight: $btn-font-weight;
text-align: center;
@include transition($btn-transition);
}
.scss
特點是與 CSS 相當類似,所以大多網頁設計師都可以無痛使用。
為什麼要學預處理器
優點:變數輕鬆改,樣式千變萬化
只要修改些微的變數,就可以讓原有的模組有更多的延伸變化,不僅有效減少開發時間,更能應付多變需求。
優點:相同結構重複利用
每次專案都有許多可重複運用的元件、樣式,與其這樣不如每次都收集起來,不再重複造輪子,輕鬆愜意創造新花樣。
按鈕、字體、邊線、圖片滿版都是以前做的。
-webkit-、-moz-、-o-、-ms-
優點:自動化修正
哪一個 CSS 在目前還需要前綴詞呢?
算了,那一點都不重要,Sass 可搭配 PostCSS 自動完成此功能,假設未來都不需要前綴詞,當然也可以自動移除。
所謂工程師,就是能自動就讓他自動阿。
開始學習 Sass 吧
- 如何安裝 Sass 開發環境
- 如何匯入 Bootstrap 模組及調整情境色
- 開啟 Bootstrap 隱藏樣式
- 客製化模組
- 自定義模組心法分享
在 VSCode 中加入 Sass 環境
操作步驟
- 點擊 Extensions、輸入 Live Sass Compiler 後安裝此套件
- 在專案中新增 stylesheets 資料夾、在裡面新增 all.scss 檔案後就會在 VSCode 下面看到出現 Watch Sass 功能
- 如果沒有就把 VSCode 關閉然後再以專案的形式打開
- 按下 Watch Sass 會發現新增 css 資料夾以及兩個檔案 al.css、all.css.map
- all.css 都是透過 all.scss 編譯而成,因此我們都只會在 all.scss 撰寫我們的程式碼
- 在 all.scss 檔案撰寫程式碼、存檔後會立即編譯,在 all.css 檔案就可以看到編譯完成的檔案
- 在 index.html 檔案載入 all.css,並在文字內套用 .filter 樣式
- 到瀏覽器看是否有套用樣式成功
// all.scss - 6
$primary: blue;
.filter {
filter: blur(1px);
color: $primary;
}
自我補充:如何調整編譯後檔案位置、名稱
File > Preferences > Settings > Extensions > JSON > JSON: Schemas > Edit in settings.json
// settings.json
"liveSassCompile.settings.formats": [
// 調整
// {
// "format": "compressed",
// "extensionName": ".min.css",
// "savePath": "/css"
// }
// 預設
{
"format": "expanded",
"extensionName": ".css",
"savePath": null
}
live sass compiler 前綴詞設定
設定>延伸模組> Live Sass Compiler > 在 settings.json 內編輯 加上
"liveSassCompile.settings.autoprefix": ["> 1%", "last 2 versions"] // 這項套件會自動幫你加入前綴(Prefix)
live Sass Compiler 套件在 VS Code 可以客製化的相關 setting(GitHub)
匯入 Bootstrap 並調整樣式
操作步驟
- 把 Bootstrap 加入到我們的專案
- Bootstrap 加入進來的方式有兩種
- 直接到 Bootstrap 文件下載、選擇原始檔案下載
- 使用 npm 下載 (必需先安裝 Node.js),課程會介紹這個方法
- 在 VSCode 按下 Ctrl + ` 開啟終端機
- 輸入指令 npm init 進行初始化設定,建立 package.json 檔案
- 輸入指令安裝 Bootstrap:npm install bootstrap
- 開啟 Bootstrap 官方文件,到自定義 > Sass > 匯入的地方找到引入的方法,然後貼到 all.scss 檔案中存檔,編譯完成後會在下方出現 Success 的字眼
- 在 index.html 試著把一些元件加到畫面上
- 調整 Sass 的變數,在官方有介紹使用的方法,在這個地方使用比較簡單的一個方式,點開 node_modules > bootstrap > scss > 找到 _varialbes.scss 檔案使用另存新檔到 stylesheet 資料夾裡面,老師個人比較習慣會再另外建立一個資料夾 helpers、然後按下存檔
- 在 helpers 資料夾中就有一個 _variables.scss 檔案,這邊就有 Bootstrap 所有的變數,在 all.scss 就可以把 helpers/_variables.scss 檔案引入,直接引入會產生錯誤,引此我們要先載入 functions,然後再載入 helpers/variables,存檔之後就會再次編譯並套用裡面的變數
- 打開終端機、然後跳到輸出這個分頁,再 helpers/variables 的 $theme-colors 的地方(大概81行左右的地方),我們要把 primary 的地方改成 purple、然後儲存,在 OUTPUT 的地方看是否有更動,如果沒有更動就重開 VSCode 再來試試看
- 回到瀏覽器看一下是否有套用上紫色的樣式
// all.scss - 6
@import "../node_modules/bootstrap/scss/bootstrap";
// index.html - 7
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="stylesheets/all.css">
</head>
<body>
<a href="#" class="btn btn-primary">我是按鈕</a>
</body>
</html>
// all.scss - 9
// required functions
@import "../node_modules/bootstrap/scss/functions";
// helpers/variables
@import "./helpers/variables";
@import "../node_modules/bootstrap/scss/bootstrap";
// helpers/_variables - 10
// scss-docs-start theme-colors-map
$theme-colors: (
"primary": $purple,
"secondary": $secondary,
"success": $success,
"info": $info,
"warning": $warning,
"danger": $danger,
"light": $light,
"dark": $dark
) !default;
- Getting started > Download > Source files > Download
- Customize > Sass
- Customize > Sass > Variable defaults
讓 Bootstrap 不要那麼肥,手動匯入元件
操作步驟
- 在自定義 > 優化 > 匯入 Sass 樣式從 @import “mixins”; 以下開始複製並貼到 all.scss、把原本匯入的 bootstrap 取代,這個路徑是錯誤的
- 修正路徑,可以使用垂直圈選、或者使用 ctrl + d 圈選,把路徑修改後,就可以刪除部分元件,前三個要保留起來,是 Bootstrap 的預設值,後面的就可以進行一些選用,我們現在就把大部分的元件註解掉,編譯完成後可以看檔案大小變成多少
- 比較常用到的元件有 images, containers, grid, tables, forms, buttons, helpers, utilities,其他沒用到建議可以不用載入
// all.scss - 3
// required functions
@import "../node_modules/bootstrap/scss/functions";
// helpers/variables
@import "./helpers/variables";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/utilities";
// Layout & components
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
// @import "../node_modules/bootstrap/scss/transitions";
// @import "../node_modules/bootstrap/scss/dropdown";
// @import "../node_modules/bootstrap/scss/button-group";
// @import "../node_modules/bootstrap/scss/nav";
// @import "../node_modules/bootstrap/scss/navbar";
// @import "../node_modules/bootstrap/scss/card";
// @import "../node_modules/bootstrap/scss/accordion";
// @import "../node_modules/bootstrap/scss/breadcrumb";
// @import "../node_modules/bootstrap/scss/pagination";
// @import "../node_modules/bootstrap/scss/badge";
// @import "../node_modules/bootstrap/scss/alert";
// @import "../node_modules/bootstrap/scss/progress";
// @import "../node_modules/bootstrap/scss/list-group";
// @import "../node_modules/bootstrap/scss/close";
// @import "../node_modules/bootstrap/scss/toasts";
// @import "../node_modules/bootstrap/scss/modal";
// @import "../node_modules/bootstrap/scss/tooltip";
// @import "../node_modules/bootstrap/scss/popover";
// @import "../node_modules/bootstrap/scss/carousel";
// @import "../node_modules/bootstrap/scss/spinners";
// @import "../node_modules/bootstrap/scss/offcanvas";
// @import "../node_modules/bootstrap/scss/placeholders";
// // Helpers
@import "../node_modules/bootstrap/scss/helpers";
// // Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
垂直圈選:
Mac: option + 左鍵
Windows: 滑鼠中鍵
課程補充
影片中的 Bootstrap 為 5.1.3 版,若同學下載的是 5.2 版以上的版本,要記得 import 時,需使用新版 import 的檔案與順序。
5.2:
// Configuration
@import "functions";
@import "variables";
@import "maps";
@import "mixins";
@import "utilities";
官方文件參考: https://getbootstrap.com/docs/5.2/customize/optimize/
5.3:
// Configuration
@import "functions";
@import "variables";
@import "variables-dark";
@import "maps";
@import "mixins";
@import "utilities";
官方文件參考: https://getbootstrap.com/docs/5.3/customize/optimize/
修改特定的元件的變數
介紹 Bootstrap 中的 Sass 變數有哪些是可以做調整的。
操作步驟
- 第一種方法是在文件中看到有哪些變數是可以調整的,像是格線系統,我們可以從排版 > 網格 > Sass,是在說明 Bootstrap 的 Sass 是如何建構、提供哪些變數可以做調整,在 helpers/_variables.scss 檔案中找到 $grid-columns,把它改成16、然後存檔。
- 第二種方式直接搜尋變數名稱,例如 radius。另外我們也可以直接搜尋模組,例如 btn、card。
- 直接調整全部的圓角設定。在自己在設定變數的時候常會把原本的註解起來,然後把自己的變數設定加在前面。方便自己之後搜尋自己自定義變數的設定可以在後面註解加上 custom。存檔之後就會發現所有的元件都會加上大圓角。
- 不希望所有元件都加上大圓角,就可以到特定的元件做調整,像是按鈕的元件。在習慣上會把按鈕和 input 共用相同的設定值。
- 關於 utilities 調整方式就不太一樣,示範 spacing。可以在 helpers/_variables.scss 檔案搜尋 spacing 或者搜尋 spacer 也可以。
// all.scss - 設定
// 需要 functions
@import "../node_modules/bootstrap/scss/functions";
// 自定義 helpers/variables
@import "./helpers/variables";
// Configuration
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/utilities";
// 排版 & 元件
// 基本預設
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
// 常用
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
// 會用到
@import "../node_modules/bootstrap/scss/card";
// 工具 Helpers
@import "../node_modules/bootstrap/scss/helpers";
// 通用類別 Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Live Sass</title>
<link rel="stylesheet" href="stylesheets/all.css">
<style>
.box {
height: 100px;
background-color: var(--bs-primary);
}
</style>
</head>
<body>
<div class="container my-3">
<div class="row">
<div class="col-6"><div class="box"></div></div>
<div class="col-6"><div class="box"></div></div>
<div class="col-4"><div class="box"></div></div>
</div>
<hr>
<a href="#" class="btn btn-primary me-7">我是按鈕</a>
<a href="#" class="btn btn-primary">我是按鈕</a>
<hr>
<div class="mb-3">
<label for="exampleFormControlInput1" class="form-label">Email address</label>
<input type="email" class="form-control" id="exampleFormControlInput1" placeholder="name@example.com">
</div>
<div class="mb-3">
<label for="exampleFormControlTextarea1" class="form-label">Example textarea</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
<hr>
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
<a href="#" class="card-link">Card link</a>
<a href="#" class="card-link">Another link</a>
</div>
</div>
</div>
</body>
</html>
// helpers/_variables.scss - 3
// Grid columns
//
// Set the number of columns and specify the width of the gutters.
$grid-columns: 16; // 12 !default;
$grid-gutter-width: 1.5rem !default;
$grid-row-columns: 6 !default;
$gutters: $spacers !default;
// scss-docs-start border-radius-variables
$border-radius: 1rem; // .25rem !default; custom
$border-radius-sm: .2rem !default;
$border-radius-lg: .3rem !default;
$border-radius-pill: 50rem !default;
// scss-docs-end border-radius-variables
// helpers/_variables.scss - 4
// Allows for customizing button radius independently from global border radius
$btn-border-radius: 1rem; // $border-radius !default; custom
$btn-border-radius-sm: $border-radius-sm !default;
$btn-border-radius-lg: $border-radius-lg !default;
// scss-docs-start form-input-variables
$input-border-radius: 1rem; //$border-radius !default; custom
$input-border-radius-sm: $border-radius-sm !default;
$input-border-radius-lg: $border-radius-lg !default;
// Cards
// scss-docs-start card-variables
$card-spacer-y: $spacer !default;
$card-spacer-x: $spacer !default;
$card-title-spacer-y: $spacer * .5 !default;
$card-border-width: $border-width !default;
$card-border-color: rgba($black, .125) !default;
$card-border-radius: 0; // $border-radius !default; custom
$card-box-shadow: null !default;
$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default;
$card-cap-padding-y: $card-spacer-y * .5 !default;
$card-cap-padding-x: $card-spacer-x !default;
$card-cap-bg: rgba($black, .03) !default;
$card-cap-color: null !default;
$card-height: null !default;
$card-color: null !default;
$card-bg: $white !default;
$card-img-overlay-padding: $spacer !default;
$card-group-margin: $grid-gutter-width * .5 !default;
// scss-docs-end card-variables
// helpers/_variables.scss - 5
// Spacing
//
// Control the default styling of most Bootstrap elements by modifying these
// variables. Mostly focused on spacing.
// You can add more entries to the $spacers map, should you need more variation.
// scss-docs-start spacer-variables-maps
$spacer: 1rem !default;
$spacers: (
0: 0,
1: $spacer * .25,
2: $spacer * .5,
3: $spacer,
4: $spacer * 1.5,
5: $spacer * 3,
6: $spacer * 4.5,
7: $spacer * 6,
) !default;
$negative-spacers: if($enable-negative-margins, negativify-map($spacers), null) !default;
// scss-docs-end spacer-variables-maps
Bootstrap 隱藏功能開關!
操作步驟
- 我們可以到自定義 > 選項找到 $enable-gradients 是關於背景漸層變數的名稱,然後到 helpers/_variables.scss 搜尋該變數做修改、儲存。
- 啟用的方式是我們先加上原本的變數名稱,然後在加上一個 bg-gradient 就可以套用。加上之後,他其實不是只有背景加上漸層色,是所有的元件都加上漸層色、視覺效果。
- 還有另外一個陰影的設定 $enable-shadows
// helpers/_variables.scss - 1
// Options
//
// Quickly modify global styling by enabling or disabling optional features.
$enable-caret: true !default;
$enable-rounded: true !default;
$enable-shadows: false !default;
$enable-gradients: true; // false !default; custom
$enable-transitions: true !default;
$enable-reduced-motion: true !default;
$enable-smooth-scroll: true !default;
$enable-grid-classes: true !default;
$enable-cssgrid: false !default;
$enable-button-pointers: true !default;
$enable-rfs: true !default;
$enable-validation-icons: true !default;
$enable-negative-margins: false !default;
$enable-deprecation-messages: true !default;
$enable-important-utilities: true !default;
// index.html - 2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Live Sass</title>
<link rel="stylesheet" href="stylesheets/all.css">
<style>
.box {
height: 100px;
background-color: var(--bs-primary);
}
</style>
</head>
<body>
<div class="container my-3">
<div class="row">
<div class="col-6"><div class="box bg-primary bg-gradient"></div></div>
<div class="col-6"><div class="box"></div></div>
<div class="col-4"><div class="box"></div></div>
</div>
<hr>
<a href="#" class="btn btn-primary me-7">我是按鈕</a>
<a href="#" class="btn btn-primary">我是按鈕</a>
<hr>
<div class="mb-3">
<label for="exampleFormControlInput1" class="form-label">Email address</label>
<input type="email" class="form-control" id="exampleFormControlInput1" placeholder="name@example.com">
</div>
<div class="mb-3">
<label for="exampleFormControlTextarea1" class="form-label">Example textarea</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
<hr>
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
<a href="#" class="card-link">Card link</a>
<a href="#" class="card-link">Another link</a>
</div>
</div>
</div>
</body>
</html>
// helpers/_variables.scss - 3
// Options
//
// Quickly modify global styling by enabling or disabling optional features.
$enable-caret: true !default;
$enable-rounded: true !default;
$enable-shadows: true; // false !default; custom
$enable-gradients: true; // false !default; custom
$enable-transitions: true !default;
$enable-reduced-motion: true !default;
$enable-smooth-scroll: true !default;
$enable-grid-classes: true !default;
$enable-cssgrid: false !default;
$enable-button-pointers: true !default;
$enable-rfs: true !default;
$enable-validation-icons: true !default;
$enable-negative-margins: false !default;
$enable-deprecation-messages: true !default;
$enable-important-utilities: true !default;
響應式文字縮放功能
如果不喜歡這個功能,可以在 helpers/_variables.scss 檔案把 $enable-rfs 關閉
自定義通用類別
操作步驟
- 製作範例、接下來再透過指定的通用類別讓這個畫面呈現更加完善
- 要使用 utilities 該怎麼做,進入 node_modules > bootstrap > scss >_utilities.scss,另存新檔到 helpers 資料夾裡面
- 到官方文件了解到底要怎樣去定義,然後在官方這裡有提供一個範例,在官方的範例我們可以加入到 helpers/_utilities.scss 最後面
- 要記得把 helpers/utilities 匯入到 all.scss 裡面來
- 因為圖片裡面的物品並不是放在正中央,我們需要加入第二組自訂定位的 utilities
- 增加額外的選項,就是響應式的選項,可以在 helpers/utilities.scss 加上 responsive 的屬性
// helpers/_utilites.scss - 第一組自訂背景的 utilities
// custom background
"background-size": (
property: background-size,
class: bg-s,
values: (
cover: cover,
contain: contain,
50: 50%
)
)
// all.scss
// 需要 functions
@import "../node_modules/bootstrap/scss/functions";
// 自定義 helpers/variables
@import "./helpers/variables";
// 自定義 helpers/utilities
@import "./helpers/utilities";
// Configuration
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/utilities";
// 排版 & 元件
// 基本預設
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
// 常用
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
// 會用到
@import "../node_modules/bootstrap/scss/card";
// 工具 Helpers
@import "../node_modules/bootstrap/scss/helpers";
// 通用類別 Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
// helpers/utilities.scss - 第二組自訂定位的 utilities
// custom background
"background-size": (
property: background-size,
class: bg-s,
values: (
cover: cover,
contain: contain,
50: 50%
)
),
"background-position": (
property: background-position,
class: bg-p,
values: (
center: center center,
)
)
// helpers/utilities - 6
// custom background
"background-size": (
property: background-size,
class: bg-s,
values: (
cover: cover,
contain: contain,
50: 50%
)
),
"background-position": (
property: background-position,
responsive: true,
class: bg-p,
values: (
center: center center,
)
)
// utilities.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Live Sass</title>
<link rel="stylesheet" href="stylesheets/all.css">
<style>
.box {
height: 100px;
background-color: var(--bs-primary);
}
</style>
</head>
<body class="vh-100 bg-s-cover bg-p-lg-center" style="background-image: url(https://images.unsplash.com/photo-1458966480358-a0ac42de0a7a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80);">
</body>
</html>
使用 Bootstrap 方法,產生獨立元件
操作步驟
- 在 helpers/utilities.scss 的 $theme-colors 加上 “hex: #69F8AE,存檔之後過一會就會套用自訂的樣式,這個方式會套用到所有的地方
- 有些情況只想在特定的元件下才啟用這個樣式的話,我們就可以使用 Bootstrap 另外提供的方法,我們先把剛才的 hex 註解起來
- 到官方文件找到文件 > 元件 > 按鈕 > Mixins,Mixins 提供非常多的方法,那這些方法在套用之後,就可以產生一個新的色彩。這邊就有提供關於按鈕產生的 Mixins button-variant 的方法,這個方法可以傳入部分色彩,就可以產生一個新的按鈕,這個按鈕就不是透過變數的方式所產生,而是透過額外的方法。具體的話,該如何運用它,我們可以再往下可以看到他有一個套用的方式,他是使用 @include 的方式把這個方法給引入進來,那後面會載入兩個色彩
- 在 stylesheets 裡面新增一個資料夾,這也算是個人的習慣,會使用一個新的資料夾來存放所有的元件,那這個資料夾名稱就叫 components。那在這個資料夾內可以再產生一個新的檔案,這個檔案叫做 _custom-buttons.scss,這 _(下底線)就會讓這個 sass 檔案不會被實際編譯一個獨立的檔案。
- 我們把 all.scss 打開,在最下方的地方我們把這隻檔案給引入進來
- 在 _custom-buttons.scss 開始編輯這支檔案,
// component.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Live Sass</title>
<link rel="stylesheet" href="./stylesheets/all.css">
</head>
<style>
.box {
height: 100px;
background-color: var(--bs-primary);
}
</style>
<body>
<button type="button" class="btn btn-primary">這是按鈕</button>
<button type="button" class="btn btn-hex">這是按鈕</button>
</body>
</html>
// helpers/_variables.scss - 5.引入獨立元件
// scss-docs-start theme-colors-map
$theme-colors: (
"primary": $purple,
"hex": #69F0AE,
"secondary": $secondary,
"success": $success,
"info": $info,
"warning": $warning,
"danger": $danger,
"light": $light,
"dark": $dark
) !default;
// scss-docs-end theme-colors-map
// all.scss
// 需要 functions
@import "../node_modules/bootstrap/scss/functions";
// 自定義 helpers/variables
@import "./helpers/variables";
// 自定義 helpers/utilities
@import "./helpers/utilities";
// Configuration
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/utilities";
// 排版 & 元件
// 基本預設
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
// 常用
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
// 會用到
@import "../node_modules/bootstrap/scss/card";
// 工具 Helpers
@import "../node_modules/bootstrap/scss/helpers";
// 通用類別 Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
// 獨立元件
@import "./components/custom-buttons";
// _custom-buttons.scss - 6
.btn-custom-hex {
@include button-variant(#69F0AE, #69F0AE)
}
.btn-outline-hex {
@include button-outline-variant(#69F0AE)
}
// components.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Live Sass</title>
<link rel="stylesheet" href="./stylesheets/all.css">
</head>
<style>
.box {
height: 100px;
background-color: var(--bs-primary);
}
</style>
<body>
<button type="button" class="btn btn-primary">這是按鈕</button>
<button type="button" class="btn btn-custom-hex">這是按鈕</button>
<button type="button" class="btn btn-outline-hex">這是按鈕</button>
</body>
</html>
在 Sass 中,自訂高可用性的元件
操作步驟
- 自訂元件的概念就是當你引入 Bootstrap 的時候,你的元件不夠使用需要自行做開發的時候,會怎麼做比較好,那這一段沒有一個絕對的做法,在此只是分享在實作中會怎麼樣去自訂元件。
- 使用方式過去到現在差異不大,這是 Bootstrap 4 進行開發的時候會定義 all.scss、components、helpers,那跟目前版本的 Bootstrap 5 介紹的內容其實差異不大,helpers 資料夾裡面會放 _variables.scss、_utilities.scss 這兩個變數檔,各種元件會把它放在 components 資料夾裡面。在定義元件的時候,盡可能維持一個概念,在定義元件的時候預期這個元件就是可以被重複利用的,所以不管它是放在哪個頁面預期就是可以把它拿過來使用,所以它才會叫做元件。
- 透過元件範例進行介紹,我們在建立元件的過程中可以給它一個名稱,名稱可以用它的外觀來進行命名,比如說它就是一個進度條的外觀,那就可以給它一個 stepbar,這種命名沒有絕對的對錯,最外層的部分會一個叫做 stepbar,那內層的話在命名的過程中就會延續這個 stepbar 的名稱做開頭,後面再依它的需求進行調整,比如說這是 stepbar 的各個子項目,那它就叫做 stepbar-item。
- 當我們建立完 stepbar 這個元件之後,在 all.scss 把 components/_stepbar.scss 把它引入進來。在每個元件檔名前面都會有一個下底線避免編譯成獨立的檔案。
- 在 components/_stepbar.scss 開發上面盡可能維持一些原則,如果是個 sass 新手的話,建議把整個 CSS 檔案寫進來就好、然後套用一些變數。
- 如果是有經驗的 sass 開發者的話,以下事項要稍微注意一下,第一個就是許多 sass 開發者會過度的利用 sass 的層級功能,像是在 .stepbar-item 這邊如果你有子項目的時候,許多新手 sass 開發者,他會不斷的用巢狀寫下去,這是一個非常不好的寫法。如果當你遇到多個層級的時候,建議把它改成使用這種方式去做撰寫,當你的巢狀寫法跟這種寫法的結果是一模一樣的時候,請不要過度巢狀。過度巢狀是一個非常不好的寫法,除非它有特別的用意。在 Bootstrap 裡面也會避免過度巢狀,那如果它使用巢狀,那是有它的意義在,如果沒有它的意義在,請不要過度巢狀。第二點是盡可能使用變數,變數的話可以看這個範例,在 background-color 這裡有使用 $primary 的顏色,這個 $primary 是來自 Bootstrap 的變數,透過這種方式就可以確保當前的元件是符合 Bootstrap 的色彩。在這個元件下需要自訂屬於這個元件自訂的變數,當有這個需求可以把變數定義在 _variables.scss 這支檔案。另一種方式就是把變數定義在當前的元件內,這個變數就只會給予這個元件所使用,所以在這個地方有個 $size,那它就是給後面這個 $size 所套用,我們在畫面上就會看到這個元件大小是 1.5 rem。如果覺得 size 太小就可以統一使用變數來做調整,這樣的好處是說,當有許多地方跟這個尺寸、變數有連動的時候,只要調整一個地方,所有地方就會跟著統一做修改。
- 除此之外還有一個叫做狀態,我們在開發一個元件,它可能有不同的主題色彩或者不同的狀態,像是 hover、active 都是屬於狀態,會習慣統一把狀態往後放。所以在這邊會有個 stepbar,往後找就會找到一個 stepbar-item.active 當它啟用的時候就可以加上 active 的樣式,就會統一放在同一個區塊,好處就是當它有其他狀態的時候,就可以在狀態這個片段程式碼來進行調整。剛剛有把 $size 改成 3rem,所以我們再回到瀏覽器來看一下,就可以看到進度條它的尺寸變大了許多。
- 這個章就是介紹 sass 跟 Bootstrap 的混合運用方式。
// custom-components.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Live Sass</title>
<link rel="stylesheet" href="stylesheets/all.css">
</head>
<body>
<div class="container">
<h1>自訂元件</h1>
<div class="stepbar my-3">
<span class="stepbar-item">1</span>
<span class="stepbar-item active">2</span>
<span class="stepbar-item">3</span>
</div>
<div class="stepbar my-3">
<span class="stepbar-item">1</span>
<span class="stepbar-item">2</span>
<span class="stepbar-item active">3</span>
<span class="stepbar-item">4</span>
<span class="stepbar-item">5</span>
</div>
<div class="stepbar my-3">
<span class="stepbar-item">1</span>
<span class="stepbar-item">2</span>
<span class="stepbar-item">3</span>
</div>
</div>
</body>
</html>
// all.scss - 4
// 需要 functions
@import "../node_modules/bootstrap/scss/functions";
// 自定義 helpers/variables
@import "./helpers/variables";
// 自定義 helpers/utilities
@import "./helpers/utilities";
// Configuration
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/utilities";
// 排版 & 元件
// 基本預設
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
// 常用
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
// 會用到
@import "../node_modules/bootstrap/scss/card";
// 工具 Helpers
@import "../node_modules/bootstrap/scss/helpers";
// 通用類別 Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
// 獨立元件
@import "./components/custom-buttons";
@import "./components/stepbar";
// components/stepbar
.stepbar {
// 原則 1:避免過多層級
// 原則 2:盡可能使用變數
$size: 3rem;
display: flex;
justify-content: space-between;
position: relative;
&::after {
content: "";
top: 50%;
left: 0;
right: 0;
height: 1px;
background-color: lighten($primary, 20%);
transform: translateY(-50%);
position: absolute;
z-index: -1;
}
// level 1 外層
.stepbar-item {
background-color: $primary;
width: $size;
height: $size;
border-radius: $size;
border: 1px solid white;
color: white;
display: flex;
justify-content: center;
align-items: center;
}
// 2
// ...
.stepbar-inner {
}
// 狀態
.stepbar-item.active {
box-shadow: 0 0 0 1px $primary;
}
.stepbar-item.active ~ .stepbar-item {
background-color: $gray-500;
}
}
CH11 – 學員專屬:Bootstrap 額外元件範例
學員專屬:Bootstrap 額外範例說明
額外元件範例資源下載
下載請參考附近
此資源僅提供給予註冊「Bootstrap 5 網頁切版整合術」的學員使用。
CH12 – 個人簡歷 – 練習使用 Sass 變數開發網頁
個人簡歷:匯入 Sass
- 安裝 package.json 檔案 – npm init
- 安裝 Bootstrap 套件 npm install bootstrap
- 建立 stylesheets 資料夾,在裡面建立 helpers 資料夾,從 node_modules 資料夾複製 _utilities.scss、_variables.scss 檔案到 helpers 資料夾裡面
- 建立 all.scss 檔案把 Bootstrap 匯入進來,可參考 Bootstrap 文件檔案,匯入 helpers 資料夾的 variables、utilities 檔案
- 使用 Watch Sass 把 all.scss 檔案編譯成 all.css 檔案
- 建立 index.html 檔案與內容、載入 all.css
- 修改 helpers/_variables.scss 檔案的 theme-color-variables,$primary: #9b5d42;、$secondary: #2a2e22;,主色彩和次色彩可以從圖片經由 Chrome Console 用吸取工具吸取調整,然後儲存
- 使用 VSCode 用 Live Server 開啟網頁
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>個人簡歷-Sass開發</title>
<link rel="stylesheet" href="./stylesheets/all.css">
</head>
<body>
<div class="container">
<img src="https://images.unsplash.com/photo-1501002138038-06806ed23bce?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80" alt="">
<a href="#" class="btn btn-primary">按鈕</a>
<a href="#" class="btn btn-secondary">按鈕</a>
</div>
</body>
</html>
// all.scss
// Configuration
@import "../node_modules/bootstrap/scss/functions";
@import "./helpers/variables";
@import "./helpers/utilities";
@import "../node_modules/bootstrap/scss/mixins";
// Layout & components
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
@import "../node_modules/bootstrap/scss/transitions";
@import "../node_modules/bootstrap/scss/dropdown";
@import "../node_modules/bootstrap/scss/button-group";
@import "../node_modules/bootstrap/scss/nav";
@import "../node_modules/bootstrap/scss/navbar";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/accordion";
@import "../node_modules/bootstrap/scss/breadcrumb";
@import "../node_modules/bootstrap/scss/pagination";
@import "../node_modules/bootstrap/scss/badge";
@import "../node_modules/bootstrap/scss/alert";
@import "../node_modules/bootstrap/scss/progress";
@import "../node_modules/bootstrap/scss/list-group";
@import "../node_modules/bootstrap/scss/close";
@import "../node_modules/bootstrap/scss/toasts";
@import "../node_modules/bootstrap/scss/modal";
@import "../node_modules/bootstrap/scss/tooltip";
@import "../node_modules/bootstrap/scss/popover";
@import "../node_modules/bootstrap/scss/carousel";
@import "../node_modules/bootstrap/scss/spinners";
@import "../node_modules/bootstrap/scss/offcanvas";
@import "../node_modules/bootstrap/scss/placeholders";
// Helpers
@import "../node_modules/bootstrap/scss/helpers";
// Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
// stylesheets/helpers/_variables.scss
// scss-docs-start theme-color-variables
$primary: #9b5d42; // $blue !default;
$secondary: #2a2e22; // $gray-600 !default;
$success: $green !default;
$info: $cyan !default;
$warning: $yellow !default;
$danger: $red !default;
$light: $gray-100 !default;
$dark: $gray-900 !default;
// scss-docs-end theme-color-variables
個人簡歷:課程相關資源
本章節運用的大頭照連結 (課練習抽取色彩):
個人練習採用圖片
個人簡歷:Header 首圖製作
// index.html - 個人簡歷: Header 首圖製作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>個人簡歷-Sass開發</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<style>
.bg-cover {
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
}
.bg-attachment-fixed {
background-attachment: fixed;
}
.deco-box {
height: 240px;
width: 240px;
background-color: var(--bs-secondary);
}
</style>
</head>
<body>
<header class="min-vh-100 position-relative">
<div class="deco-box position-absolute top-0 start-0"></div>
<div class="deco-box position-absolute bottom-0 end-0"></div>
<div class="position-absolute bg-cover bg-attachment-fixed" style="top: 30px; left: 30px; right: 30px; bottom: 30px; background-image: url(https://images.unsplash.com/photo-1501002138038-06806ed23bce?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80)"></div>
<div class="position-absolute top-50 start-50 translate-middle text-center text-success">
<h1 class="display-1 fw-bold">背包客</h1>
<hr class="mb-1 mx-n3">
<h2>Backpacker</h2>
<p>在對的道路上迷失是件多麼美好的事情。</p>
</div>
</header>
</body>
</html>
// all.scss
// Configuration
@import "../node_modules/bootstrap/scss/functions";
@import "./helpers/variables";
@import "./helpers/utilities";
@import "../node_modules/bootstrap/scss/mixins";
// Layout & components
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
@import "../node_modules/bootstrap/scss/transitions";
@import "../node_modules/bootstrap/scss/dropdown";
@import "../node_modules/bootstrap/scss/button-group";
@import "../node_modules/bootstrap/scss/nav";
@import "../node_modules/bootstrap/scss/navbar";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/accordion";
@import "../node_modules/bootstrap/scss/breadcrumb";
@import "../node_modules/bootstrap/scss/pagination";
@import "../node_modules/bootstrap/scss/badge";
@import "../node_modules/bootstrap/scss/alert";
@import "../node_modules/bootstrap/scss/progress";
@import "../node_modules/bootstrap/scss/list-group";
@import "../node_modules/bootstrap/scss/close";
@import "../node_modules/bootstrap/scss/toasts";
@import "../node_modules/bootstrap/scss/modal";
@import "../node_modules/bootstrap/scss/tooltip";
@import "../node_modules/bootstrap/scss/popover";
@import "../node_modules/bootstrap/scss/carousel";
@import "../node_modules/bootstrap/scss/spinners";
@import "../node_modules/bootstrap/scss/offcanvas";
@import "../node_modules/bootstrap/scss/placeholders";
// Helpers
@import "../node_modules/bootstrap/scss/helpers";
// Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
// helpers/_variables.scss
// scss-docs-start theme-color-variables
$primary: #9b5d42; // $blue !default;
$secondary: #2a2e22; // $gray-600 !default;
$success: $green !default;
$info: $cyan !default;
$warning: $yellow !default;
$danger: $red !default;
$light: $gray-100 !default;
$dark: $gray-900 !default;
// scss-docs-end theme-color-variables
// Options
//
// Quickly modify global styling by enabling or disabling optional features.
$enable-caret: true !default;
$enable-rounded: true !default;
$enable-shadows: false !default;
$enable-gradients: false !default;
$enable-transitions: true !default;
$enable-reduced-motion: true !default;
$enable-smooth-scroll: true !default;
$enable-grid-classes: true !default;
$enable-cssgrid: false !default;
$enable-button-pointers: true !default;
$enable-rfs: true !default;
$enable-validation-icons: true !default;
$enable-negative-margins: true; // false !default;
$enable-deprecation-messages: true !default;
$enable-important-utilities: true !default;
個人簡歷:自我介紹區塊
// index.html - 個人簡歷: 自我介紹區塊
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>個人簡歷-Sass開發</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<style>
.bg-cover {
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
}
.bg-attachment-fixed {
background-attachment: fixed;
}
.object-fit-cover {
object-fit: cover;
}
.deco-box {
height: 240px;
width: 240px;
background-color: var(--bs-secondary);
}
</style>
</head>
<body>
<!-- 個人簡歷: Header 首圖製作 start -->
<header class="min-vh-100 position-relative">
<div class="deco-box position-absolute top-0 start-0"></div>
<div class="deco-box position-absolute bottom-0 end-0"></div>
<div class="position-absolute bg-cover bg-attachment-fixed" style="top: 30px; left: 30px; right: 30px; bottom: 30px; background-image: url(https://images.unsplash.com/photo-1501002138038-06806ed23bce?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80)"></div>
<div class="position-absolute top-50 start-50 translate-middle text-center text-success">
<h1 class="display-1 fw-bold">背包客</h1>
<hr class="mb-1 mx-n3">
<h2>Backpacker</h2>
<p>在對的道路上迷失是件多麼美好的事情。</p>
</div>
</header>
<!-- 個人簡歷: Header 首圖製作 end -->
<!-- 個人簡歷: 自我介紹區塊 start -->
<div class="container py-5">
<div class="row gy-3 justify-content-center flex-md-row-reverse">
<div class="col-md-4">
<img src="https://images.unsplash.com/photo-1509467283235-ad1568d50691?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80" class="w-100 object-fit-cover" height="500" alt="">
</div>
<div class="col-md-5 d-flex align-items-center">
<div>
<h2 class="display-4">我的旅遊類型:</h2>
<p>背包客(英語:backpacker,衍生自backpacking一詞),就是背著背包做長途自助旅行的人,被稱呼為背包客的旅行者往往是在有限的預算下進行旅行活動,所以他們對於旅行的規劃、景點的獨到之處也常有自成一派的見解。</p>
<p>在旅遊界裡,擁有豐富經驗的背包客往往相當受人關注,此外,目前背包客也能泛指登山、露營、冒險活動的戶外活動參與者。類似旅遊形式還有沙發客,以低預算甚至免費的形式進行旅遊。</p>
<a href="#" class="btn btn-outline-primary mt-4 w-100">
看更多我的旅遊類型
</a>
</div>
</div>
</div>
</div>
<!-- 個人簡歷: 自我介紹區塊 end -->
</body>
</html>
個人簡歷:三欄式卡片運用
在實作中建議先做其中一個就好了,因為在製作過程中會不斷調整,等到第一張卡片確定都沒有問題之後,再複製到下一張卡片。
個人練習採用圖片
// index.html - 個人簡歷: 三欄式卡片運用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>個人簡歷-Sass開發</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<style>
.bg-cover {
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
}
.bg-attachment-fixed {
background-attachment: fixed;
}
.object-fit-cover {
object-fit: cover;
}
.deco-box {
height: 240px;
width: 240px;
background-color: var(--bs-secondary);
}
</style>
</head>
<body>
<!-- 個人簡歷: Header 首圖製作 start -->
<header class="min-vh-100 position-relative">
<div class="deco-box position-absolute top-0 start-0"></div>
<div class="deco-box position-absolute bottom-0 end-0"></div>
<div class="position-absolute bg-cover bg-attachment-fixed" style="top: 30px; left: 30px; right: 30px; bottom: 30px; background-image: url(https://images.unsplash.com/photo-1501002138038-06806ed23bce?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80)"></div>
<div class="position-absolute top-50 start-50 translate-middle text-center text-success">
<h1 class="display-1 fw-bold">背包客</h1>
<hr class="mb-1 mx-n3">
<h2>Backpacker</h2>
<p>在對的道路上迷失是件多麼美好的事情。</p>
</div>
</header>
<!-- 個人簡歷: Header 首圖製作 end -->
<!-- 個人簡歷: 自我介紹區塊 start -->
<div class="container py-5">
<div class="row gy-3 justify-content-center flex-md-row-reverse">
<div class="col-md-4">
<img src="https://images.unsplash.com/photo-1509467283235-ad1568d50691?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80" class="w-100 object-fit-cover" height="500" alt="">
</div>
<div class="col-md-5 d-flex align-items-center">
<div>
<h2 class="display-4">我的旅遊類型:</h2>
<p>背包客(英語:backpacker,衍生自backpacking一詞),就是背著背包做長途自助旅行的人,被稱呼為背包客的旅行者往往是在有限的預算下進行旅行活動,所以他們對於旅行的規劃、景點的獨到之處也常有自成一派的見解。</p>
<p>在旅遊界裡,擁有豐富經驗的背包客往往相當受人關注,此外,目前背包客也能泛指登山、露營、冒險活動的戶外活動參與者。類似旅遊形式還有沙發客,以低預算甚至免費的形式進行旅遊。</p>
<a href="#" class="btn btn-outline-primary mt-4 w-100">
看更多我的旅遊類型
</a>
</div>
</div>
</div>
</div>
<!-- 個人簡歷: 自我介紹區塊 end -->
<!-- 個人簡歷: 三欄式卡片運用 start -->
<div class="bg-light py-5 m-md-5">
<div class="container">
<h2 class="display-4 text-center mb-4">
我的旅遊景點:
</h2>
<div class="row row-cols-1 row-cols-lg-3 g-4">
<div class="col">
<div class="card bg-dark text-white">
<img src="..." class="card-img" alt="...">
<div class="card-img-overlay">
<h5 class="card-title">Card title</h5>
<p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
<p class="card-text">Last updated 3 mins ago</p>
</div>
</div>
</div>
<div class="col">
<div class="card bg-dark text-white">
<img src="..." class="card-img" alt="...">
<div class="card-img-overlay">
<h5 class="card-title">Card title</h5>
<p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
<p class="card-text">Last updated 3 mins ago</p>
</div>
</div>
</div>
<div class="col">
<div class="card bg-dark text-white">
<img src="..." class="card-img" alt="...">
<div class="card-img-overlay">
<h5 class="card-title">Card title</h5>
<p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
<p class="card-text">Last updated 3 mins ago</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 個人簡歷: 三欄式卡片運用 end -->
</body>
</html>
個人簡歷:卡片樣式調整
// index.html - 卡片樣式調整
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>個人簡歷-Sass開發</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<style>
.bg-cover {
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
}
.bg-attachment-fixed {
background-attachment: fixed;
}
.bg-dark-gradient {
/* linear-gradient(方向性, 色彩); */
background-image: linear-gradient(180deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.8));
}
.object-fit-cover {
object-fit: cover;
}
.deco-box {
height: 240px;
width: 240px;
background-color: var(--bs-secondary);
}
</style>
</head>
<body>
<!-- 個人簡歷: Header 首圖製作 start -->
<header class="min-vh-100 position-relative">
<div class="deco-box position-absolute top-0 start-0"></div>
<div class="deco-box position-absolute bottom-0 end-0"></div>
<div class="position-absolute bg-cover bg-attachment-fixed" style="top: 30px; left: 30px; right: 30px; bottom: 30px; background-image: url(https://images.unsplash.com/photo-1501002138038-06806ed23bce?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80)"></div>
<div class="position-absolute top-50 start-50 translate-middle text-center text-success">
<h1 class="display-1 fw-bold">背包客</h1>
<hr class="mb-1 mx-n3">
<h2>Backpacker</h2>
<p>在對的道路上迷失是件多麼美好的事情。</p>
</div>
</header>
<!-- 個人簡歷: Header 首圖製作 end -->
<!-- 個人簡歷: 自我介紹區塊 start -->
<div class="container py-5">
<div class="row gy-3 justify-content-center flex-md-row-reverse">
<div class="col-md-4">
<img src="https://images.unsplash.com/photo-1509467283235-ad1568d50691?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80" class="w-100 object-fit-cover" height="500" alt="">
</div>
<div class="col-md-5 d-flex align-items-center">
<div>
<h2 class="display-4">我的旅遊類型:</h2>
<p>背包客(英語:backpacker,衍生自backpacking一詞),就是背著背包做長途自助旅行的人,被稱呼為背包客的旅行者往往是在有限的預算下進行旅行活動,所以他們對於旅行的規劃、景點的獨到之處也常有自成一派的見解。</p>
<p>在旅遊界裡,擁有豐富經驗的背包客往往相當受人關注,此外,目前背包客也能泛指登山、露營、冒險活動的戶外活動參與者。類似旅遊形式還有沙發客,以低預算甚至免費的形式進行旅遊。</p>
<a href="#" class="btn btn-outline-primary mt-4 w-100">
看更多我的旅遊類型
</a>
</div>
</div>
</div>
</div>
<!-- 個人簡歷: 自我介紹區塊 end -->
<!-- 個人簡歷: 三欄式卡片運用 start -->
<!-- 個人簡歷: 卡片樣式調整 start -->
<div class="bg-light p-md-5 py-5 m-md-5">
<div class="container">
<h2 class="display-4 text-center mb-4">
我的旅遊景點:
</h2>
<div class="row row-cols-1 row-cols-lg-3 g-4">
<div class="col">
<div class="card text-white border-5 h-100">
<img src="https://images.unsplash.com/photo-1534570122623-99e8378a9aa7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80" class="card-img h-100 object-fit-cover" alt="...">
<div class="card-img-overlay top-auto bg-dark-gradient">
<h5 class="card-title">在海邊與大海近距離接觸</h5>
<p class="card-text">在海邊可以望向大海,藉由海浪的聲音消除心中的壓力,在此刻我們與大海在此刻像是彼此訴說的朋友。</p>
<a href="#" class="btn btn-outline-light stretched-link w-100">看內容</a>
</div>
</div>
</div>
<div class="col">
<div class="card text-white border-5 h-100">
<img src="https://images.unsplash.com/photo-1553808354-cda09bba39dc?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80" class="card-img h-100 object-fit-cover" alt="...">
<div class="card-img-overlay top-auto bg-dark-gradient">
<h5 class="card-title">在山中生活與草木相伴</h5>
<p class="card-text">在山中可以望向高山,藉由山中的慢步調與自然景觀,我們可以在此與草木相伴,就像有朋友靜靜地陪伴一樣。</p>
<a href="#" class="btn btn-outline-light stretched-link w-100">看內容</a>
</div>
</div>
</div>
<div class="col">
<div class="card text-white border-5 h-100">
<img src="https://images.unsplash.com/photo-1598920710727-e6c74781538c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80" class="card-img h-100 object-fit-cover" alt="...">
<div class="card-img-overlay top-auto bg-dark-gradient">
<h5 class="card-title">向陽下的向日葵花海</h5>
<p class="card-text">在好天氣下的向日葵花海,周圍花香環繞,我們可以聞著花香、看著一望無際的花海,讓我們身心上的心靈再次滋養。</p>
<a href="#" class="btn btn-outline-light stretched-link w-100">看內容</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 個人簡歷: 卡片樣式調整 end -->
<!-- 個人簡歷: 三欄式卡片運用 end -->
</body>
</html>
// helpers/_variables.scss - 新增 $position-values 的 auto 樣式
// Position
//
// Define the edge positioning anchors of the position utilities.
// scss-docs-start position-map
$position-values: (
0: 0,
50: 50%,
100: 100%,
auto: auto
) !default;
// scss-docs-end position-map
個人簡歷:Footer 製作及表單驗證樣式調整
// index.html - 個人簡歷: Footer 製作及表單驗證樣式調整
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>個人簡歷-Sass開發</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
<style>
.bg-cover {
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
}
.bg-attachment-fixed {
background-attachment: fixed;
}
.bg-dark-gradient {
/* linear-gradient(方向性, 色彩); */
background-image: linear-gradient(180deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.8));
}
.object-fit-cover {
object-fit: cover;
}
.deco-box {
height: 240px;
width: 240px;
background-color: var(--bs-secondary);
}
</style>
</head>
<body>
<!-- 個人簡歷: Header 首圖製作 start -->
<header class="min-vh-100 position-relative">
<div class="deco-box position-absolute top-0 start-0"></div>
<div class="deco-box position-absolute bottom-0 end-0"></div>
<div class="position-absolute bg-cover bg-attachment-fixed" style="top: 30px; left: 30px; right: 30px; bottom: 30px; background-image: url(https://images.unsplash.com/photo-1501002138038-06806ed23bce?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80)"></div>
<div class="position-absolute top-50 start-50 translate-middle text-center text-success">
<h1 class="display-1 fw-bold">背包客</h1>
<hr class="mb-1 mx-n3">
<h2>Backpacker</h2>
<p>在對的道路上迷失是件多麼美好的事情。</p>
</div>
</header>
<!-- 個人簡歷: Header 首圖製作 end -->
<!-- 個人簡歷: 自我介紹區塊 start -->
<div class="container py-5">
<div class="row gy-3 justify-content-center flex-md-row-reverse">
<div class="col-md-4">
<img src="https://images.unsplash.com/photo-1509467283235-ad1568d50691?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80" class="w-100 object-fit-cover" height="500" alt="">
</div>
<div class="col-md-5 d-flex align-items-center">
<div>
<h2 class="display-4">我的旅遊類型:</h2>
<p>背包客(英語:backpacker,衍生自backpacking一詞),就是背著背包做長途自助旅行的人,被稱呼為背包客的旅行者往往是在有限的預算下進行旅行活動,所以他們對於旅行的規劃、景點的獨到之處也常有自成一派的見解。</p>
<p>在旅遊界裡,擁有豐富經驗的背包客往往相當受人關注,此外,目前背包客也能泛指登山、露營、冒險活動的戶外活動參與者。類似旅遊形式還有沙發客,以低預算甚至免費的形式進行旅遊。</p>
<a href="#" class="btn btn-outline-primary mt-4 w-100">
看更多我的旅遊類型
</a>
</div>
</div>
</div>
</div>
<!-- 個人簡歷: 自我介紹區塊 end -->
<!-- 個人簡歷: 三欄式卡片運用 start -->
<!-- 個人簡歷: 卡片樣式調整 start -->
<div class="bg-light p-md-5 py-5 m-md-5">
<div class="container">
<h2 class="display-4 text-center mb-4">
我的旅遊景點:
</h2>
<div class="row row-cols-1 row-cols-lg-3 g-4">
<div class="col">
<div class="card text-white border-5 h-100">
<img src="https://images.unsplash.com/photo-1534570122623-99e8378a9aa7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80" class="card-img h-100 object-fit-cover" alt="...">
<div class="card-img-overlay top-auto bg-dark-gradient">
<h5 class="card-title">在海邊與大海近距離接觸</h5>
<p class="card-text">在海邊可以望向大海,藉由海浪的聲音消除心中的壓力,在此刻我們與大海在此刻像是彼此訴說的朋友。</p>
<a href="#" class="btn btn-outline-light stretched-link w-100">看內容</a>
</div>
</div>
</div>
<div class="col">
<div class="card text-white border-5 h-100">
<img src="https://images.unsplash.com/photo-1553808354-cda09bba39dc?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80" class="card-img h-100 object-fit-cover" alt="...">
<div class="card-img-overlay top-auto bg-dark-gradient">
<h5 class="card-title">在山中生活與草木相伴</h5>
<p class="card-text">在山中可以望向高山,藉由山中的慢步調與自然景觀,我們可以在此與草木相伴,就像有朋友靜靜地陪伴一樣。</p>
<a href="#" class="btn btn-outline-light stretched-link w-100">看內容</a>
</div>
</div>
</div>
<div class="col">
<div class="card text-white border-5 h-100">
<img src="https://images.unsplash.com/photo-1598920710727-e6c74781538c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80" class="card-img h-100 object-fit-cover" alt="...">
<div class="card-img-overlay top-auto bg-dark-gradient">
<h5 class="card-title">向陽下的向日葵花海</h5>
<p class="card-text">在好天氣下的向日葵花海,周圍花香環繞,我們可以聞著花香、看著一望無際的花海,讓我們身心上的心靈再次滋養。</p>
<a href="#" class="btn btn-outline-light stretched-link w-100">看內容</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 個人簡歷: 卡片樣式調整 end -->
<!-- 個人簡歷: 三欄式卡片運用 end -->
<!-- 個人簡歷: Footer 製作及表單驗證樣式調整 start -->
<footer class="bg-primary p-5 text-white">
<div class="container">
<h2 class="display-4 text-center">做個背包客吧:</h2>
<div class="row justify-content-center">
<div class="col-md-5">
<p>有共同的興趣將能搭起友誼的橋樑</p>
<h3 class="h4">聯絡方式</h3>
<ul class="list-unstyled">
<li><i class="bi bi-envelope"></i> backpacker@email.com</li>
<li><i class="bi bi-telephone"></i> 0989-123-456</li>
</ul>
<h3 class="h4 mt-5">社群關注</h3>
<ul class="list-unstyled">
<li><i class="bi bi-instagram"></i> backpacker</li>
<li><i class="bi bi-facebook"></i> fb.me/backpacker</li>
<li><i class="bi bi-twitter"></i> backpacker</li>
</ul>
<p>© 2022 by Backpacker. Created with Bootstrap 5.</p>
<p>Code by Gee Hsu.</p>
</div>
<form class="col-md-5 needs-validation" novalidate>
<div class="row g-2">
<div class="col-md-6">
<label for="validationServer01" class="form-label">姓氏 *</label>
<input type="text" class="form-control" id="validationServer01" placeholder="背" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-md-6">
<label for="validationServer02" class="form-label">名 *</label>
<input type="text" class="form-control" id="validationServer02" placeholder="包客" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="mb-3 col-12">
<label for="exampleFormControlInput1" class="form-label">Email *</label>
<input type="email" class="form-control" id="exampleFormControlInput1" placeholder="name@example.com" required>
<div class="invalid-feedback">
請輸入 Email,拜託
</div>
</div>
<div class="mb-3 col-12">
<label for="exampleFormControlTextarea1" class="form-label">留些訊息給我吧 *</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3" required></textarea>
</div>
<div class="text-end col-12">
<button class="btn btn-outline-light" type="submit">送出表單</button>
</div>
</div>
</form>
</div>
</div>
</footer>
<!-- 個人簡歷: Footer 製作及表單驗證樣式調整 end -->
<script>
// 表單驗證
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function () {
'use strict'
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.querySelectorAll('.needs-validation')
// Loop over them and prevent submission
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)
})
})()
</script>
</body>
</html>
// helpers/_variables.scss
// 修改驗證顏色方式一
// scss-docs-start theme-color-variables
$primary: #9b5d42; // $blue !default;
$secondary: #2a2e22; // $gray-600 !default;
$success: #00ff89; // $green !default;
$info: $cyan !default;
$warning: $yellow !default;
$danger: $red !default;
$light: $gray-100 !default;
$dark: $gray-900 !default;
// scss-docs-end theme-color-variables
// 修改驗證顏色方式二
// Form validation
// scss-docs-start form-feedback-variables
$form-feedback-margin-top: $form-text-margin-top !default;
$form-feedback-font-size: $form-text-font-size !default;
$form-feedback-font-style: $form-text-font-style !default;
$form-feedback-valid-color: $success !default;
$form-feedback-invalid-color: #f1aeb5; // $danger !default;
$form-feedback-icon-valid-color: $form-feedback-valid-color !default;
$form-feedback-icon-valid: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>") !default;
$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;
$form-feedback-icon-invalid: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>") !default;
// scss-docs-end form-feedback-variables
個人簡歷:整理 Sass 專案檔案
操作步驟
- 在 stylesheets 資料夾建立 components 資料夾,並在 components 資料夾新增 _deco-box.scss 檔案,從 helpers/_variables.scss 檔案把 $secondary 變數貼到 _deco-box.scss 的 background-color 地方
- 在 all.scss 把 _deco-box.scss 檔案引入進來
- 把可以定義成 utilities 的樣式從 index.html <style> 給抽離出來,建議所抽離的是比較單純的樣式,通常自己客製化的會加在最下面,像是在這邊的 .bg-attachment-fixed 這個就可以把它加到我們的 helpers/_utilities.scss 檔案裡面來
- 打開 helpers/_utilities.scss 檔案,自定義的設定會放在最後面的地方,這裡可以加入我們自己的 utilities,可以先加上 custom 的註解,然後接下來我們就把相關的自定義樣式給建立起來。首先建立的第一個是我們的 .bg-attachment-fixed 這一個,把 bg-attachment 這個名稱先放在這個前面,然後加入一個大括號,加入大括號之後我們要定義的屬性 property,我們要使用的屬性會是 background-attachment 的這個屬性,那我們就把這個屬性給貼過來,貼過來之後我們會再補一個逗號。目前來說這有一個問題應該是用小括號而不是大括號,因為寫 JS 的話是使用一個花括號,但在這個地方必需使用小括號。那要注意如果你這邊畫面上如果出現像這樣有個紅色的一個提示,代表我們撰寫有錯誤,目前來說這邊要使用逗號,然後我們在前面的 “visibility” 後面這邊括號後面還要補上一個逗號,這樣才是正確的。這邊我們使用的 class name 是 bg-attachment 的,那我們就把這個 bg-attachment 也把它貼過來,這是我們要用的 class name。在後面可以撰寫相對應的一些樣式,那麼所適用的樣式目前只有使用 fixed,那麼我們可以先加入 fixed 就好,那這樣的話我們就會把這樣式加入到 utilities 統一進行管理。
- 那我們再把另外一個樣式也把它給加進來,另外一個樣式就是 object-fit 這個樣式,我們使用相同的方式把它給貼過來,然後它所套用的屬性則是另外一個屬性 object-fit,那我們把它貼過來,那它所套用的值則是 cover。如果說你有其他的值,像是 contain 或者是其他的 object-fit 會用到的值,也都可以加到 values 裡面。存檔之後就可以把在 <style> 裡面的 .object-fit-cover、.bg-attachment-fixed 給移除,存檔之後回到畫面上可以得到一個相同的結果。我們可以看到畫面上的底圖它一樣是固定在原位,就算我們把 <style> 的樣式清除掉。
- 接下來再畫面上還有一個 .bg-cover、以及 .bg-dark-gradient 這兩個就不一定適合放到 utilities 裡面,那這個時候該怎麼做,會比較建議在 components 資料夾再新增一個 _utilities.scss 檔案,這個檔案就放剩餘不知道該怎麼做管理的單獨樣式,就可以放在這個檔案裡面。如果太多的話,建議稍作整理,然後把它抽離出來。這邊就把剩餘的一些樣式把它給放過來,一樣把 <style> 清空之後存檔。當然我們把它獨立成一個檔案之後,我們一樣回到 all.scss 必需把它匯入進來才可以做運作,我們一樣使用 @import 的方式把剛剛剩餘的 utilities 給匯入進來,存檔之後等到它編譯完成,在畫面上就可以看到這些樣式
// stylesheets/components/_deco-box.scss
.deco-box {
height: 240px;
width: 240px;
background-color: $secondary;
}
// all.scss - 2
// Configuration
@import "../node_modules/bootstrap/scss/functions";
@import "./helpers/variables";
@import "./helpers/utilities";
@import "../node_modules/bootstrap/scss/mixins";
// Layout & components
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
@import "../node_modules/bootstrap/scss/transitions";
@import "../node_modules/bootstrap/scss/dropdown";
@import "../node_modules/bootstrap/scss/button-group";
@import "../node_modules/bootstrap/scss/nav";
@import "../node_modules/bootstrap/scss/navbar";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/accordion";
@import "../node_modules/bootstrap/scss/breadcrumb";
@import "../node_modules/bootstrap/scss/pagination";
@import "../node_modules/bootstrap/scss/badge";
@import "../node_modules/bootstrap/scss/alert";
@import "../node_modules/bootstrap/scss/progress";
@import "../node_modules/bootstrap/scss/list-group";
@import "../node_modules/bootstrap/scss/close";
@import "../node_modules/bootstrap/scss/toasts";
@import "../node_modules/bootstrap/scss/modal";
@import "../node_modules/bootstrap/scss/tooltip";
@import "../node_modules/bootstrap/scss/popover";
@import "../node_modules/bootstrap/scss/carousel";
@import "../node_modules/bootstrap/scss/spinners";
@import "../node_modules/bootstrap/scss/offcanvas";
@import "../node_modules/bootstrap/scss/placeholders";
// Helpers
@import "../node_modules/bootstrap/scss/helpers";
// Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
// components
@import "./components/deco-box";
// helpers/_utilities.scss
// custom
"bg-attachment": (
property: background-attachment,
class: "bg-attachment",
values: fixed
),
"object-fit": (
property: object-fit,
class: "object-fit",
values: cover
)
// components/_utilities.scss
.bg-cover {
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
}
.bg-dark-gradient {
/* linear-gradient(方向性, 色彩); */
background-image: linear-gradient(180deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.8));
}
// all.scss
// components
@import "./components/deco-box";
@import "./components/utilities";
個人簡歷:範例作業下載
注意:
- 此檔案僅用來參考,請勿複製程式碼
CH13 – 後台管理 – 功能性為導向的介面規劃
後台管理:章節說明
操作步驟
- 使用 npm init 建立 package.json 檔案
- 使用 npm 安裝 Bootstrap,npm install bootstrap
- 建立 stylesheets 資料夾,在裡面建立 components、helpers 資料夾
- 從 node_modules > bootstrap > scss 裡面的 _variables.scss、_utilities.scss 複製到 helpers 資料夾裡面
- 使用 Watch Sass 從 scss 檔案編譯成 css 檔案
- 建立 index.html 把 all.css、bootstrap icons cdn 載入
- 建立 .gitignore 檔案
// all.scss
// Configuration
@import "../node_modules/bootstrap/scss/functions";
@import "./helpers/variables";
@import "./helpers/utilities";
@import "../node_modules/bootstrap/scss/mixins";
// Layout & components
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
@import "../node_modules/bootstrap/scss/transitions";
@import "../node_modules/bootstrap/scss/dropdown";
@import "../node_modules/bootstrap/scss/button-group";
@import "../node_modules/bootstrap/scss/nav";
@import "../node_modules/bootstrap/scss/navbar";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/accordion";
@import "../node_modules/bootstrap/scss/breadcrumb";
@import "../node_modules/bootstrap/scss/pagination";
@import "../node_modules/bootstrap/scss/badge";
@import "../node_modules/bootstrap/scss/alert";
@import "../node_modules/bootstrap/scss/progress";
@import "../node_modules/bootstrap/scss/list-group";
@import "../node_modules/bootstrap/scss/close";
@import "../node_modules/bootstrap/scss/toasts";
@import "../node_modules/bootstrap/scss/modal";
@import "../node_modules/bootstrap/scss/tooltip";
@import "../node_modules/bootstrap/scss/popover";
@import "../node_modules/bootstrap/scss/carousel";
@import "../node_modules/bootstrap/scss/spinners";
@import "../node_modules/bootstrap/scss/offcanvas";
@import "../node_modules/bootstrap/scss/placeholders";
// Helpers
@import "../node_modules/bootstrap/scss/helpers";
// Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 首頁</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
</body>
</html>
// .gitignore
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
後台管理:結構規劃
// index.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 首頁</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end">
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom">
<a href="#" class="d-inline-block py-3 px-4 border-end">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
</body>
</html>
// components/_sidebar.scss
$sidebar-width: 280px;
.sidebar {
width: $sidebar-width;
}
.main {
width: calc(100vw - #{$sidebar-width});
// 變數視為一個字串
}
// all.scss
// Configuration
@import "../node_modules/bootstrap/scss/functions";
@import "./helpers/variables";
@import "./helpers/utilities";
@import "../node_modules/bootstrap/scss/mixins";
// Layout & components
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
@import "../node_modules/bootstrap/scss/transitions";
@import "../node_modules/bootstrap/scss/dropdown";
@import "../node_modules/bootstrap/scss/button-group";
@import "../node_modules/bootstrap/scss/nav";
@import "../node_modules/bootstrap/scss/navbar";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/accordion";
@import "../node_modules/bootstrap/scss/breadcrumb";
@import "../node_modules/bootstrap/scss/pagination";
@import "../node_modules/bootstrap/scss/badge";
@import "../node_modules/bootstrap/scss/alert";
@import "../node_modules/bootstrap/scss/progress";
@import "../node_modules/bootstrap/scss/list-group";
@import "../node_modules/bootstrap/scss/close";
@import "../node_modules/bootstrap/scss/toasts";
@import "../node_modules/bootstrap/scss/modal";
@import "../node_modules/bootstrap/scss/tooltip";
@import "../node_modules/bootstrap/scss/popover";
@import "../node_modules/bootstrap/scss/carousel";
@import "../node_modules/bootstrap/scss/spinners";
@import "../node_modules/bootstrap/scss/offcanvas";
@import "../node_modules/bootstrap/scss/placeholders";
// Helpers
@import "../node_modules/bootstrap/scss/helpers";
// Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
// components
@import "./components/sidebar";
後台管理:可收合的側欄選單
算是這個章節比較複雜的部份。
製作內容說明
- 製作行動版、桌面版的差異
- 選單收合
- 套用 JS
// components/_sidebar.scss
$sidebar-width: 280px;
// 行動版 (預設)
.sidebar {
width: $sidebar-width;
margin-left: -$sidebar-width;
transition: margin-left .25s;
}
.main {
width: 100%;
}
// 展開 sidebar
.sidebar-toggled {
.sidebar {
margin-left: 0;
}
}
// 桌面版(up)
@include media-breakpoint-up(lg) {
.sidebar {
margin-left: 0;
width: $sidebar-width;
}
.main {
width: calc(100vw - #{$sidebar-width});
// 變數視為一個字串
}
// 展開
.sidebar-toggled {
.sidebar {
margin-left: -$sidebar-width;
}
.main {
width: 100%;
margin-left: 0;
}
}
}
// javascripts/all.js
const toggleMenuBtn = document.querySelector('#toggle-btn');
const body = document.querySelector('body');
toggleMenuBtn.addEventListener('click', (evt) => {
// console.log(evt);
evt.preventDefault();
body.classList.toggle('sidebar-toggled');
});
// index.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 首頁</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end">
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom">
<a href="#" class="d-inline-block py-3 px-4 border-end" id="toggle-btn">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
<script src="./javascripts/all.js"></script>
</body>
</html>
後台管理:側欄選單內容
側欄選單內容的程式碼:
// CSS
.sidebar {
.sidebar-link {
color: $dark;
display: block;
text-decoration: none;
padding-top: 0.875rem;
padding-bottom: 0.875rem;
&:hover {
background-color: rgba($primary, 0.16);
}
}
.sidebar-link.active {
position: relative;
color: $primary !important;
background-color: rgba($primary, 0.16);
&::after {
content: "";
position: absolute;
top: 0;
left: 2px;
height: 100%;
width: 3px;
background: $primary;
}
}
}
// stylesheets/components/_sidebar.scss
$sidebar-width: 280px;
// 行動版 (預設)
.sidebar {
width: $sidebar-width;
margin-left: -$sidebar-width;
transition: margin-left .25s;
// sidebar-link
.sidebar-link {
color: $dark;
display: block;
text-decoration: none;
padding-top: 0.875rem;
padding-bottom: 0.875rem;
&:hover {
background-color: rgba($primary, 0.16);
}
}
.sidebar-link.active {
position: relative;
color: $primary !important;
background-color: rgba($primary, 0.16);
&::after {
content: "";
position: absolute;
top: 0;
left: 2px;
height: 100%;
width: 3px;
background: $primary;
}
}
}
.main {
width: 100%;
}
// 展開 sidebar
.sidebar-toggled {
.sidebar {
margin-left: 0;
}
}
// 桌面版(up)
@include media-breakpoint-up(lg) {
.sidebar {
margin-left: 0;
width: $sidebar-width;
}
.main {
width: calc(100vw - #{$sidebar-width});
// 變數視為一個字串
}
// 展開
.sidebar-toggled {
.sidebar {
margin-left: -$sidebar-width;
}
.main {
width: 100%;
margin-left: 0;
}
}
}
// index.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 首頁</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end pt-3 d-flex bg-white flex-column">
<!-- 1. 後台名稱 -->
<div class="px-4">
<strong>食品專賣店</strong>
- 後台管理
</div>
<!-- 2. 選單 -->
<div class="overflow-auto mt-3">
<div>
<a href="#" class="sidebar-link active">
<div class="px-4">
<i class="bi bi-house me-2"></i>
首頁
</div>
</a>
</div>
<div>
<a href="#menu-order" class="sidebar-link" data-bs-toggle="collapse">
<div class="d-flex justify-content-between px-4">
<p class="mb-0">
<i class="bi bi-card-checklist me-2"></i>
訂單管理
</p>
<i class="bi bi-caret-down"></i>
</div>
</a>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
其他項目
</div>
</a>
</div>
</div>
</div>
<!-- 3. 登出按鈕 -->
<a href="#" class="mt-auto sidebar-link">
<div class="px-4">
<i class="bi bi-box-arrow-right me-2"></i>
登出
</div>
</a>
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom">
<a href="#" class="d-inline-block py-3 px-4 border-end" id="toggle-btn">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
<script src="./javascripts/all.js"></script>
</body>
</html>
// helpers/_variables.scss
// scss-docs-start theme-color-variables
$primary: #973aa8; // $blue !default;
$secondary: $gray-600 !default;
$success: $green !default;
$info: $cyan !default;
$warning: $yellow !default;
$danger: $red !default;
$light: $gray-100 !default;
$dark: $gray-900 !default;
// scss-docs-end theme-color-variables
後台管理:版型整理
側欄和導覽列每個頁面是共用的,在實戰中會使用後端的 Template language 製作,前端方式會用 Vue, React 來製作。
以這堂課程來說不會介紹這些技術,那如何管理這些共用的版型,會比較建議目前製作的部分 index.html 改名為 layout.html 檔案。
接下來如果你要調整外面的版型都從 layout.html 去做調整,到時候再覆蓋到原始的檔案,就比較不會出錯。
// layout.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 首頁</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end pt-3 d-flex bg-white flex-column">
<!-- 1. 後台名稱 -->
<div class="px-4">
<strong>食品專賣店</strong>
- 後台管理
</div>
<!-- 2. 選單 -->
<div class="overflow-auto mt-3">
<div>
<a href="#" class="sidebar-link active">
<div class="px-4">
<i class="bi bi-house me-2"></i>
首頁
</div>
</a>
</div>
<div>
<a href="#menu-order" class="sidebar-link" data-bs-toggle="collapse">
<div class="d-flex justify-content-between px-4">
<p class="mb-0">
<i class="bi bi-card-checklist me-2"></i>
訂單管理
</p>
<i class="bi bi-caret-down"></i>
</div>
</a>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
其他項目
</div>
</a>
</div>
</div>
</div>
<!-- 3. 登出按鈕 -->
<a href="#" class="mt-auto sidebar-link">
<div class="px-4">
<i class="bi bi-box-arrow-right me-2"></i>
登出
</div>
</a>
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom sticky-top">
<a href="#" class="d-inline-block py-3 px-4 border-end" id="toggle-btn">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
<div>
<!-- 主要內容 -->
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
<script src="./javascripts/all.js"></script>
</body>
</html>
// stylesheets/components/_sidebar.scss
$sidebar-width: 280px;
// 行動版 (預設)
.sidebar {
width: $sidebar-width;
margin-left: -$sidebar-width;
transition: margin-left .25s;
position: fixed;
top: 0;
// sidebar-link
.sidebar-link {
color: $dark;
display: block;
text-decoration: none;
padding-top: 0.875rem;
padding-bottom: 0.875rem;
&:hover {
background-color: rgba($primary, 0.16);
}
}
.sidebar-link.active {
position: relative;
color: $primary !important;
background-color: rgba($primary, 0.16);
&::after {
content: "";
position: absolute;
top: 0;
left: 2px;
height: 100%;
width: 3px;
background: $primary;
}
}
}
.main {
width: 100%;
}
// 展開 sidebar
.sidebar-toggled {
.sidebar {
margin-left: 0;
}
.main {
margin-left: $sidebar-width;
}
}
// 桌面版(up)
@include media-breakpoint-up(lg) {
.sidebar {
margin-left: 0;
width: $sidebar-width;
}
.main {
width: calc(100vw - #{$sidebar-width});
margin-left: $sidebar-width;
transition: margin-left .25s;
// 變數視為一個字串
}
// 展開
.sidebar-toggled {
.sidebar {
margin-left: -$sidebar-width;
}
.main {
width: 100%;
margin-left: 0;
}
}
}
後台管理:常見卡片區塊結構
// layout.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 首頁</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end pt-3 d-flex bg-white flex-column">
<!-- 1. 後台名稱 -->
<div class="px-4">
<strong>食品專賣店</strong>
- 後台管理
</div>
<!-- 2. 選單 -->
<div class="overflow-auto mt-3">
<div>
<a href="#" class="sidebar-link active">
<div class="px-4">
<i class="bi bi-house me-2"></i>
首頁
</div>
</a>
</div>
<div>
<a href="#menu-order" class="sidebar-link" data-bs-toggle="collapse">
<div class="d-flex justify-content-between px-4">
<p class="mb-0">
<i class="bi bi-card-checklist me-2"></i>
訂單管理
</p>
<i class="bi bi-caret-down"></i>
</div>
</a>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
其他項目
</div>
</a>
</div>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-card-list me-2"></i>
產品列表
</div>
</a>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-list-stars me-2"></i>
顧客評價
</div>
</a>
</div>
</div>
<!-- 3. 登出按鈕 -->
<a href="#" class="mt-auto sidebar-link">
<div class="px-4">
<i class="bi bi-box-arrow-right me-2"></i>
登出
</div>
</a>
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom sticky-top">
<a href="#" class="d-inline-block py-3 px-4 border-end" id="toggle-btn">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
<div>
<!-- 主要內容 -->
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
<script src="./javascripts/all.js"></script>
</body>
</html>
// home.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 首頁</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end pt-3 d-flex bg-white flex-column">
<!-- 1. 後台名稱 -->
<div class="px-4">
<strong>食品專賣店</strong>
- 後台管理
</div>
<!-- 2. 選單 -->
<div class="overflow-auto mt-3">
<div>
<a href="#" class="sidebar-link active">
<div class="px-4">
<i class="bi bi-house me-2"></i>
首頁
</div>
</a>
</div>
<div>
<a href="#menu-order" class="sidebar-link" data-bs-toggle="collapse">
<div class="d-flex justify-content-between px-4">
<p class="mb-0">
<i class="bi bi-card-checklist me-2"></i>
訂單管理
</p>
<i class="bi bi-caret-down"></i>
</div>
</a>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
其他項目
</div>
</a>
</div>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-card-list me-2"></i>
產品列表
</div>
</a>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-list-stars me-2"></i>
顧客評價
</div>
</a>
</div>
</div>
<!-- 3. 登出按鈕 -->
<a href="#" class="mt-auto sidebar-link">
<div class="px-4">
<i class="bi bi-box-arrow-right me-2"></i>
登出
</div>
</a>
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom sticky-top">
<a href="#" class="d-inline-block py-3 px-4 border-end" id="toggle-btn">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
<div class="p-4">
<!-- 主要內容 -->
<div class="row g-4 row-cols-lg-3 mb-4">
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body text-end">
<h2 class="display-6">在線人數</h2>
<p class="display-4 mb-0">
3,996
</p>
</div>
</div>
</div>
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body text-end">
<h2 class="display-6">訂單數</h2>
<p class="display-4 mb-0">1,022</p>
</div>
</div>
</div>
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body text-end">
<h2 class="display-6">營業額</h2>
<p class="mb-0 text-success"><span class="fs-3">NT$</span><span class="display-4">120,500</span></p>
</div>
</div>
</div>
</div>
<div class="row g-4">
<div class="col-lg-4">
<div class="card shadow-sm h-100">
<div class="card-body">
<canvas id="pie-chart" class="img-fluid"></canvas>
</div>
</div>
</div>
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body">
<canvas id="bar-chart" class="img-fluid"></canvas>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="./javascripts/all.js"></script>
</body>
</html>
// helpers/_variables.scss
// scss-docs-start border-radius-variables
$border-radius: .25rem !default;
$border-radius-sm: .2rem !default;
$border-radius-lg: .75rem; // .3rem !default;
$border-radius-pill: 50rem !default;
// scss-docs-end border-radius-variables
// Cards
// scss-docs-start card-variables
$card-spacer-y: $spacer !default;
$card-spacer-x: $spacer !default;
$card-title-spacer-y: $spacer * .5 !default;
$card-border-width: $border-width !default;
$card-border-color: rgba($black, .125) !default;
$card-border-radius: $border-radius-lg; // $border-radius !default;
$card-box-shadow: null !default;
$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default;
$card-cap-padding-y: $card-spacer-y * .5 !default;
$card-cap-padding-x: $card-spacer-x !default;
$card-cap-bg: rgba($black, .03) !default;
$card-cap-color: null !default;
$card-height: null !default;
$card-color: null !default;
$card-bg: $white !default;
$card-img-overlay-padding: $spacer !default;
$card-group-margin: $grid-gutter-width * .5 !default;
// scss-docs-end card-variables
// javascripts/all.js
const toggleMenuBtn = document.querySelector('#toggle-btn');
const body = document.querySelector('body');
toggleMenuBtn.addEventListener('click', (evt) => {
// console.log(evt);
evt.preventDefault();
body.classList.toggle('sidebar-toggled');
});
// 動態圖表
(() => {
const chartColors = {
red: 'rgb(255, 99, 132)',
orange: 'rgb(255, 159, 64)',
yellow: 'rgb(255, 205, 86)',
green: 'rgb(75, 192, 192)',
blue: 'rgb(54, 162, 235)',
purple: 'rgb(153, 102, 255)',
grey: 'rgb(201, 203, 207)'
};
var randomScalingFactor = function () {
return Math.round(Math.random() * 2000000);
};
const pieCtx = document.getElementById('pie-chart').getContext('2d');
const barCtx = document.getElementById('bar-chart').getContext('2d');
const config = {
type: 'pie',
data: {
datasets: [{
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
chartColors.red,
chartColors.orange,
chartColors.yellow,
chartColors.green,
chartColors.blue,
],
label: 'Dataset 1'
}],
labels: [
'餅乾類',
'飲料類',
'熟食類',
'生鮮類',
'糖果類',
]
},
options: {
responsive: true
}
};
const barConfig = {
type: 'bar',
data: {
datasets: [{
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
chartColors.red,
chartColors.orange,
chartColors.yellow,
chartColors.green,
chartColors.blue,
chartColors.purple,
],
label: '單月營業額'
}],
labels: [
'一月',
'二月',
'三月',
'四月',
'五月',
'六月',
]
},
options: {
responsive: true
}
};
const pieChart = new Chart(pieCtx, config);
const barChart = new Chart(barCtx, barConfig);
})();
後台管理:動態圖表範例程式碼
動態圖表範例程式碼
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
(() => {
const chartColors = {
red: 'rgb(255, 99, 132)',
orange: 'rgb(255, 159, 64)',
yellow: 'rgb(255, 205, 86)',
green: 'rgb(75, 192, 192)',
blue: 'rgb(54, 162, 235)',
purple: 'rgb(153, 102, 255)',
grey: 'rgb(201, 203, 207)'
};
var randomScalingFactor = function () {
return Math.round(Math.random() * 2000000);
};
const pieCtx = document.getElementById('pie-chart').getContext('2d');
const barCtx = document.getElementById('bar-chart').getContext('2d');
const config = {
type: 'pie',
data: {
datasets: [{
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
chartColors.red,
chartColors.orange,
chartColors.yellow,
chartColors.green,
chartColors.blue,
],
label: 'Dataset 1'
}],
labels: [
'大麥克全餐',
'肥宅快樂水',
'太爽啦義大利麵',
'薯條加大吃不完',
'兒童餐椅不給坐',
]
},
options: {
responsive: true
}
};
const barConfig = {
type: 'bar',
data: {
datasets: [{
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
chartColors.red,
chartColors.orange,
chartColors.yellow,
chartColors.green,
chartColors.blue,
chartColors.purple,
],
label: 'Dataset 1'
}],
labels: [
'一月',
'二月',
'三月',
'四月',
'五月',
'六月',
]
},
options: {
responsive: true
}
};
const pieChart = new Chart(pieCtx, config);
const barChart = new Chart(barCtx, barConfig);
})();
</script>
後台管理:表格運用
// home.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 首頁</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end pt-3 d-flex bg-white flex-column">
<!-- 1. 後台名稱 -->
<div class="px-4">
<strong>食品專賣店</strong>
- 後台管理
</div>
<!-- 2. 選單 -->
<div class="overflow-auto mt-3">
<div>
<a href="#" class="sidebar-link active">
<div class="px-4">
<i class="bi bi-house me-2"></i>
首頁
</div>
</a>
</div>
<div>
<a href="#menu-order" class="sidebar-link" data-bs-toggle="collapse">
<div class="d-flex justify-content-between px-4">
<p class="mb-0">
<i class="bi bi-card-checklist me-2"></i>
訂單管理
</p>
<i class="bi bi-caret-down"></i>
</div>
</a>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
其他項目
</div>
</a>
</div>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-card-list me-2"></i>
產品列表
</div>
</a>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-list-stars me-2"></i>
顧客評價
</div>
</a>
</div>
</div>
<!-- 3. 登出按鈕 -->
<a href="#" class="mt-auto sidebar-link">
<div class="px-4">
<i class="bi bi-box-arrow-right me-2"></i>
登出
</div>
</a>
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom sticky-top">
<a href="#" class="d-inline-block py-3 px-4 border-end" id="toggle-btn">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
<div class="p-4">
<!-- 主要內容 -->
<div class="row g-4 row-cols-lg-3 mb-4">
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body text-end">
<h2 class="display-6">在線人數</h2>
<p class="display-4 mb-0">
3,996
</p>
</div>
</div>
</div>
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body text-end">
<h2 class="display-6">訂單數</h2>
<p class="display-4 mb-0">1,022</p>
</div>
</div>
</div>
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body text-end">
<h2 class="display-6">營業額</h2>
<p class="mb-0 text-success"><span class="fs-3">NT$</span><span class="display-4">120,500</span></p>
</div>
</div>
</div>
</div>
<div class="row g-4">
<div class="col-lg-4">
<div class="card shadow-sm h-100">
<div class="card-body">
<canvas id="pie-chart" class="img-fluid"></canvas>
</div>
</div>
</div>
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body">
<canvas id="bar-chart" class="img-fluid"></canvas>
</div>
</div>
</div>
</div>
</div>
<div class="card shadow-sm">
<div class="card-header bg-transparent">
<div class="input-group">
<span class="input-group-text border-0 bg-transparent pe-0">
<i class="bi bi-search"></i>
</span>
<input type="search" class="form-control border-0 shadow-none">
</div>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead class="bg-light text-nowrap">
<tr class="align-middle">
<th scope="col" class="py-3 ps-4">訂單編號</th>
<th scope="col">Email</th>
<th scope="col">顧客姓名</th>
<th scope="col">購買品項</th>
<th scope="col">付款狀態</th>
<th scope="col">購買金額</th>
<th scope="col" class="pe-4">編輯</th>
</tr>
</thead>
<tbody class="text-nowrap">
<tr>
<td scope="row" class="ps-4">TX20220315171601</td>
<td>bear123@email.com</td>
<td>貝小熊</td>
<td>食品專賣店:餅乾類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">600</td>
<td class="text-end pe-4">
<a href="#" class="btn btn-sm btn-outline-dark me-2">編輯 <i class="bi bi-pen"></i></a>
</td>
</tr>
<tr>
<td scope="row" class="ps-4">TX20220315170201</td>
<td>fish123@email.com</td>
<td>溪小魚</td>
<td>食品專賣店:飲料類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">1,200</td>
<td class="text-end pe-4">
<a href="#" class="btn btn-sm btn-outline-dark me-2">編輯 <i class="bi bi-pen"></i></a>
</td>
</tr>
<tr>
<td scope="row" class="ps-4">TX20220315190301</td>
<td>dog123@email.com</td>
<td>毛小熊</td>
<td>食品專賣店:熟食類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">2,200</td>
<td class="text-end pe-4">
<a href="#" class="btn btn-sm btn-outline-dark me-2">編輯 <i class="bi bi-pen"></i></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="card-footer bg-transparent py-3">
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-end mb-0">
<li class="page-item"><a class="page-link" href="#">Previous</a></li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
</nav>
</div>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="./javascripts/all.js"></script>
</body>
</html>
後台管理:訂單管理介面
// orders.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 首頁</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end pt-3 d-flex bg-white flex-column">
<!-- 1. 後台名稱 -->
<div class="px-4">
<strong>食品專賣店</strong>
- 後台管理
</div>
<!-- 2. 選單 -->
<div class="overflow-auto mt-3">
<div>
<a href="home.html" class="sidebar-link active">
<div class="px-4">
<i class="bi bi-house me-2"></i>
首頁
</div>
</a>
</div>
<div>
<a href="#menu-order" class="sidebar-link" data-bs-toggle="collapse">
<div class="d-flex justify-content-between px-4">
<p class="mb-0">
<i class="bi bi-card-checklist me-2"></i>
訂單管理
</p>
<i class="bi bi-caret-down"></i>
</div>
</a>
<div class="collapse" id="menu-order">
<a href="orders.html" class="sidebar-link">
<div class="ps-5">
訂單列表
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
單一訂單細節
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
其他項目
</div>
</a>
</div>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-card-list me-2"></i>
產品列表
</div>
</a>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-list-stars me-2"></i>
顧客評價
</div>
</a>
</div>
</div>
<!-- 3. 登出按鈕 -->
<a href="#" class="mt-auto sidebar-link">
<div class="px-4">
<i class="bi bi-box-arrow-right me-2"></i>
登出
</div>
</a>
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom sticky-top">
<a href="#" class="d-inline-block py-3 px-4 border-end" id="toggle-btn">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
<div class="p-4">
<!-- 主要內容 -->
<ul class="nav nav-pills mb-4">
<li class="nav-item">
<a class="nav-link rounded-pill active" aria-current="page" href="#">所有訂單
<span class="badge rounded-pill bg-light text-dark">156</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link rounded-pill" href="#">待處理
<span class="badge rounded-pill bg-light text-dark">106</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link rounded-pill" href="#">已出貨
<span class="badge rounded-pill bg-light text-dark">50</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link rounded-pill">退款
<span class="badge rounded-pill bg-light text-dark">2</span>
</a>
</li>
</ul>
<div class="card shadow-sm">
<div class="card-header bg-transparent">
<div class="input-group">
<div class="dropdown">
<button class="btn btn-outline-dark dropdown-toggle btn-sm" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
操作
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">全部選取</a></li>
<li><a class="dropdown-item" href="#">個別選取</a></li>
<li><a class="dropdown-item" href="#">其他</a></li>
</ul>
</div>
<span class="input-group-text border-0 bg-transparent pe-0">
<i class="bi bi-search"></i>
</span>
<input type="search" class="form-control border-0 shadow-none">
</div>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead class="bg-light text-nowrap">
<tr class="align-middle">
<th scope="col" class="ps-4"></th>
<th scope="col" class="py-3">訂單編號</th>
<th scope="col">Email</th>
<th scope="col">顧客姓名</th>
<th scope="col">購買品項</th>
<th scope="col">付款狀態</th>
<th scope="col">購買金額</th>
<th scope="col" class="pe-4">編輯</th>
</tr>
</thead>
<tbody class="text-nowrap">
<tr>
<td scope="row" class="ps-4" >
<input type="checkbox" class="form-check-input">
</td>
<td>TX20220315171601</td>
<td>bear123@email.com</td>
<td>貝小熊</td>
<td>食品專賣店:餅乾類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">600</td>
<td class="text-end pe-4">
<div class="btn-group">
<a href="#" class="btn btn-sm btn-outline-dark">編輯 <i class="bi bi-pen"></i></a>
<button class="btn btn-sm btn-outline-dark dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
操作
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">修改狀態</a></li>
<li><a class="dropdown-item" href="#">刪除訂單</a></li>
</ul>
</div>
</td>
</tr>
<tr>
<td scope="row" class="ps-4" >
<input type="checkbox" class="form-check-input">
</td>
<td>TX20220315170201</td>
<td>fish123@email.com</td>
<td>溪小魚</td>
<td>食品專賣店:飲料類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">1,200</td>
<td class="text-end pe-4">
<div class="btn-group">
<a href="#" class="btn btn-sm btn-outline-dark">編輯 <i class="bi bi-pen"></i></a>
<button class="btn btn-sm btn-outline-dark dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
操作
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">修改狀態</a></li>
<li><a class="dropdown-item" href="#">刪除訂單</a></li>
</ul>
</div>
</td>
</tr>
<tr>
<td scope="row" class="ps-4" >
<input type="checkbox" class="form-check-input">
</td>
<td>TX20220315190301</td>
<td>dog123@email.com</td>
<td>毛小熊</td>
<td>食品專賣店:熟食類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">2,200</td>
<td class="text-end pe-4">
<div class="btn-group">
<a href="#" class="btn btn-sm btn-outline-dark">編輯 <i class="bi bi-pen"></i></a>
<button class="btn btn-sm btn-outline-dark dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
操作
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">修改狀態</a></li>
<li><a class="dropdown-item" href="#">刪除訂單</a></li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="card-footer bg-transparent py-3">
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-end mb-0">
<li class="page-item"><a class="page-link" href="#">Previous</a></li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
</nav>
</div>
</div>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
<script src="./javascripts/all.js"></script>
</body>
</html>
// home.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 首頁</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end pt-3 d-flex bg-white flex-column">
<!-- 1. 後台名稱 -->
<div class="px-4">
<strong>食品專賣店</strong>
- 後台管理
</div>
<!-- 2. 選單 -->
<div class="overflow-auto mt-3">
<div>
<a href="home.html" class="sidebar-link active">
<div class="px-4">
<i class="bi bi-house me-2"></i>
首頁
</div>
</a>
</div>
<div>
<a href="#menu-order" class="sidebar-link" data-bs-toggle="collapse">
<div class="d-flex justify-content-between px-4">
<p class="mb-0">
<i class="bi bi-card-checklist me-2"></i>
訂單管理
</p>
<i class="bi bi-caret-down"></i>
</div>
</a>
<div class="collapse" id="menu-order">
<a href="orders.html" class="sidebar-link">
<div class="ps-5">
訂單列表
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
單一訂單細節
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
其他項目
</div>
</a>
</div>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-card-list me-2"></i>
產品列表
</div>
</a>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-list-stars me-2"></i>
顧客評價
</div>
</a>
</div>
</div>
<!-- 3. 登出按鈕 -->
<a href="#" class="mt-auto sidebar-link">
<div class="px-4">
<i class="bi bi-box-arrow-right me-2"></i>
登出
</div>
</a>
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom sticky-top">
<a href="#" class="d-inline-block py-3 px-4 border-end" id="toggle-btn">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
<div class="p-4">
<!-- 主要內容 -->
<div class="row g-4 row-cols-lg-3 mb-4">
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body text-end">
<h2 class="display-6">在線人數</h2>
<p class="display-4 mb-0">
3,996
</p>
</div>
</div>
</div>
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body text-end">
<h2 class="display-6">訂單數</h2>
<p class="display-4 mb-0">1,022</p>
</div>
</div>
</div>
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body text-end">
<h2 class="display-6">營業額</h2>
<p class="mb-0 text-success"><span class="fs-3">NT$</span><span class="display-4">120,500</span></p>
</div>
</div>
</div>
</div>
<div class="row g-4">
<div class="col-lg-4">
<div class="card shadow-sm h-100">
<div class="card-body">
<canvas id="pie-chart" class="img-fluid"></canvas>
</div>
</div>
</div>
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body">
<canvas id="bar-chart" class="img-fluid"></canvas>
</div>
</div>
</div>
</div>
</div>
<div class="card shadow-sm">
<div class="card-header bg-transparent">
<div class="input-group">
<span class="input-group-text border-0 bg-transparent pe-0">
<i class="bi bi-search"></i>
</span>
<input type="search" class="form-control border-0 shadow-none">
</div>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead class="bg-light text-nowrap">
<tr class="align-middle">
<th scope="col" class="py-3 ps-4">訂單編號</th>
<th scope="col">Email</th>
<th scope="col">顧客姓名</th>
<th scope="col">購買品項</th>
<th scope="col">付款狀態</th>
<th scope="col">購買金額</th>
<th scope="col" class="pe-4">編輯</th>
</tr>
</thead>
<tbody class="text-nowrap">
<tr>
<td scope="row" class="ps-4">TX20220315171601</td>
<td>bear123@email.com</td>
<td>貝小熊</td>
<td>食品專賣店:餅乾類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">600</td>
<td class="text-end pe-4">
<a href="#" class="btn btn-sm btn-outline-dark me-2">編輯 <i class="bi bi-pen"></i></a>
</td>
</tr>
<tr>
<td scope="row" class="ps-4">TX20220315170201</td>
<td>fish123@email.com</td>
<td>溪小魚</td>
<td>食品專賣店:飲料類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">1,200</td>
<td class="text-end pe-4">
<a href="#" class="btn btn-sm btn-outline-dark me-2">編輯 <i class="bi bi-pen"></i></a>
</td>
</tr>
<tr>
<td scope="row" class="ps-4">TX20220315190301</td>
<td>dog123@email.com</td>
<td>毛小熊</td>
<td>食品專賣店:熟食類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">2,200</td>
<td class="text-end pe-4">
<a href="#" class="btn btn-sm btn-outline-dark me-2">編輯 <i class="bi bi-pen"></i></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="card-footer bg-transparent py-3">
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-end mb-0">
<li class="page-item"><a class="page-link" href="#">Previous</a></li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
</nav>
</div>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="./javascripts/all.js"></script>
</body>
</html>
// layout.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 首頁</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end pt-3 d-flex bg-white flex-column">
<!-- 1. 後台名稱 -->
<div class="px-4">
<strong>食品專賣店</strong>
- 後台管理
</div>
<!-- 2. 選單 -->
<div class="overflow-auto mt-3">
<div>
<a href="home.html" class="sidebar-link active">
<div class="px-4">
<i class="bi bi-house me-2"></i>
首頁
</div>
</a>
</div>
<div>
<a href="#menu-order" class="sidebar-link" data-bs-toggle="collapse">
<div class="d-flex justify-content-between px-4">
<p class="mb-0">
<i class="bi bi-card-checklist me-2"></i>
訂單管理
</p>
<i class="bi bi-caret-down"></i>
</div>
</a>
<div class="collapse" id="menu-order">
<a href="orders.html" class="sidebar-link">
<div class="ps-5">
訂單列表
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
單一訂單細節
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
其他項目
</div>
</a>
</div>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-card-list me-2"></i>
產品列表
</div>
</a>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-list-stars me-2"></i>
顧客評價
</div>
</a>
</div>
</div>
<!-- 3. 登出按鈕 -->
<a href="#" class="mt-auto sidebar-link">
<div class="px-4">
<i class="bi bi-box-arrow-right me-2"></i>
登出
</div>
</a>
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom sticky-top">
<a href="#" class="d-inline-block py-3 px-4 border-end" id="toggle-btn">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
<div>
<!-- 主要內容 -->
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
<script src="./javascripts/all.js"></script>
</body>
</html>
後台管理:傳遞內容至 Modal 內
// orders.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 訂單列表</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end pt-3 d-flex bg-white flex-column">
<!-- 1. 後台名稱 -->
<div class="px-4">
<strong>食品專賣店</strong>
- 後台管理
</div>
<!-- 2. 選單 -->
<div class="overflow-auto mt-3">
<div>
<a href="home.html" class="sidebar-link">
<div class="px-4">
<i class="bi bi-house me-2"></i>
首頁
</div>
</a>
</div>
<div>
<a href="#menu-order" class="sidebar-link" data-bs-toggle="collapse">
<div class="d-flex justify-content-between px-4">
<p class="mb-0">
<i class="bi bi-card-checklist me-2"></i>
訂單管理
</p>
<i class="bi bi-caret-down"></i>
</div>
</a>
<div class="collapse" id="menu-order">
<a href="orders.html" class="sidebar-link active">
<div class="ps-5">
訂單列表
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
單一訂單細節
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
其他項目
</div>
</a>
</div>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-card-list me-2"></i>
產品列表
</div>
</a>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-list-stars me-2"></i>
顧客評價
</div>
</a>
</div>
</div>
<!-- 3. 登出按鈕 -->
<a href="#" class="mt-auto sidebar-link">
<div class="px-4">
<i class="bi bi-box-arrow-right me-2"></i>
登出
</div>
</a>
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom sticky-top">
<a href="#" class="d-inline-block py-3 px-4 border-end" id="toggle-btn">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
<div class="p-4">
<!-- 主要內容 -->
<ul class="nav nav-pills mb-4">
<li class="nav-item">
<a class="nav-link rounded-pill active" aria-current="page" href="#">所有訂單
<span class="badge rounded-pill bg-light text-dark">156</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link rounded-pill" href="#">待處理
<span class="badge rounded-pill bg-light text-dark">106</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link rounded-pill" href="#">已出貨
<span class="badge rounded-pill bg-light text-dark">50</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link rounded-pill">退款
<span class="badge rounded-pill bg-light text-dark">2</span>
</a>
</li>
</ul>
<div class="card shadow-sm">
<div class="card-header bg-transparent">
<div class="input-group">
<div class="dropdown">
<button class="btn btn-outline-dark dropdown-toggle btn-sm" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
操作
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">全部選取</a></li>
<li><a class="dropdown-item" href="#">個別選取</a></li>
<li><a class="dropdown-item" href="#">其他</a></li>
</ul>
</div>
<span class="input-group-text border-0 bg-transparent pe-0">
<i class="bi bi-search"></i>
</span>
<input type="search" class="form-control border-0 shadow-none">
</div>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead class="bg-light text-nowrap">
<tr class="align-middle">
<th scope="col" class="ps-4"></th>
<th scope="col" class="py-3">訂單編號</th>
<th scope="col">Email</th>
<th scope="col">顧客姓名</th>
<th scope="col">購買品項</th>
<th scope="col">付款狀態</th>
<th scope="col">購買金額</th>
<th scope="col" class="pe-4">編輯</th>
</tr>
</thead>
<tbody class="text-nowrap">
<tr>
<td scope="row" class="ps-4" >
<input type="checkbox" class="form-check-input">
</td>
<td>TX20220315171601</td>
<td>bear123@email.com</td>
<td>貝小熊</td>
<td>食品專賣店:餅乾類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">600</td>
<td class="text-end pe-4">
<div class="btn-group">
<a href="#" class="btn btn-sm btn-outline-dark">編輯 <i class="bi bi-pen"></i></a>
<button class="btn btn-sm btn-outline-dark dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
操作
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">修改狀態</a></li>
<li><a class="dropdown-item text-danger" href="#" data-bs-toggle="modal" data-bs-target="#deleteModal" data-bs-order-id="TX20220315171601">刪除訂單</a></li>
</ul>
</div>
</td>
</tr>
<tr>
<td scope="row" class="ps-4" >
<input type="checkbox" class="form-check-input">
</td>
<td>TX20220315170201</td>
<td>fish123@email.com</td>
<td>溪小魚</td>
<td>食品專賣店:飲料類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">1,200</td>
<td class="text-end pe-4">
<div class="btn-group">
<a href="#" class="btn btn-sm btn-outline-dark">編輯 <i class="bi bi-pen"></i></a>
<button class="btn btn-sm btn-outline-dark dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
操作
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">修改狀態</a></li>
<li><a class="dropdown-item text-danger" href="#" data-bs-toggle="modal" data-bs-target="#deleteModal" data-bs-order-id="TX20220315170201">刪除訂單</a></li>
</ul>
</div>
</td>
</tr>
<tr>
<td scope="row" class="ps-4" >
<input type="checkbox" class="form-check-input">
</td>
<td>TX20220315190301</td>
<td>dog123@email.com</td>
<td>毛小熊</td>
<td>食品專賣店:熟食類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">2,200</td>
<td class="text-end pe-4">
<div class="btn-group">
<a href="#" class="btn btn-sm btn-outline-dark">編輯 <i class="bi bi-pen"></i></a>
<button class="btn btn-sm btn-outline-dark dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
操作
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">修改狀態</a></li>
<li><a class="dropdown-item text-danger" href="#" data-bs-toggle="modal" data-bs-target="#deleteModal" data-bs-order-id="TX20220315190301">刪除訂單</a></li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="card-footer bg-transparent py-3">
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-end mb-0">
<li class="page-item"><a class="page-link" href="#">Previous</a></li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
</nav>
</div>
<!-- Modal -->
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">刪除訂單</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
確認刪除「<span id="deleteText"></span>」的訂單嗎?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-danger">確認刪除</button>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
<script src="./javascripts/modal.js"></script>
<script src="./javascripts/all.js"></script>
</body>
</html>
// home.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 首頁</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end pt-3 d-flex bg-white flex-column">
<!-- 1. 後台名稱 -->
<div class="px-4">
<strong>食品專賣店</strong>
- 後台管理
</div>
<!-- 2. 選單 -->
<div class="overflow-auto mt-3">
<div>
<a href="home.html" class="sidebar-link active">
<div class="px-4">
<i class="bi bi-house me-2"></i>
首頁
</div>
</a>
</div>
<div>
<a href="#menu-order" class="sidebar-link" data-bs-toggle="collapse">
<div class="d-flex justify-content-between px-4">
<p class="mb-0">
<i class="bi bi-card-checklist me-2"></i>
訂單管理
</p>
<i class="bi bi-caret-down"></i>
</div>
</a>
<div class="collapse" id="menu-order">
<a href="orders.html" class="sidebar-link">
<div class="ps-5">
訂單列表
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
單一訂單細節
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
其他項目
</div>
</a>
</div>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-card-list me-2"></i>
產品列表
</div>
</a>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-list-stars me-2"></i>
顧客評價
</div>
</a>
</div>
</div>
<!-- 3. 登出按鈕 -->
<a href="#" class="mt-auto sidebar-link">
<div class="px-4">
<i class="bi bi-box-arrow-right me-2"></i>
登出
</div>
</a>
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom sticky-top">
<a href="#" class="d-inline-block py-3 px-4 border-end" id="toggle-btn">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
<div class="p-4">
<!-- 主要內容 -->
<div class="row g-4 row-cols-lg-3 mb-4">
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body text-end">
<h2 class="display-6">在線人數</h2>
<p class="display-4 mb-0">
3,996
</p>
</div>
</div>
</div>
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body text-end">
<h2 class="display-6">訂單數</h2>
<p class="display-4 mb-0">1,022</p>
</div>
</div>
</div>
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body text-end">
<h2 class="display-6">營業額</h2>
<p class="mb-0 text-success"><span class="fs-3">NT$</span><span class="display-4">120,500</span></p>
</div>
</div>
</div>
</div>
<div class="row g-4">
<div class="col-lg-4">
<div class="card shadow-sm h-100">
<div class="card-body">
<canvas id="pie-chart" class="img-fluid"></canvas>
</div>
</div>
</div>
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-body">
<canvas id="bar-chart" class="img-fluid"></canvas>
</div>
</div>
</div>
</div>
</div>
<div class="card shadow-sm">
<div class="card-header bg-transparent">
<div class="input-group">
<span class="input-group-text border-0 bg-transparent pe-0">
<i class="bi bi-search"></i>
</span>
<input type="search" class="form-control border-0 shadow-none">
</div>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead class="bg-light text-nowrap">
<tr class="align-middle">
<th scope="col" class="py-3 ps-4">訂單編號</th>
<th scope="col">Email</th>
<th scope="col">顧客姓名</th>
<th scope="col">購買品項</th>
<th scope="col">付款狀態</th>
<th scope="col">購買金額</th>
<th scope="col" class="pe-4">編輯</th>
</tr>
</thead>
<tbody class="text-nowrap">
<tr>
<td scope="row" class="ps-4">TX20220315171601</td>
<td>bear123@email.com</td>
<td>貝小熊</td>
<td>食品專賣店:餅乾類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">600</td>
<td class="text-end pe-4">
<a href="#" class="btn btn-sm btn-outline-dark me-2">編輯 <i class="bi bi-pen"></i></a>
</td>
</tr>
<tr>
<td scope="row" class="ps-4">TX20220315170201</td>
<td>fish123@email.com</td>
<td>溪小魚</td>
<td>食品專賣店:飲料類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">1,200</td>
<td class="text-end pe-4">
<a href="#" class="btn btn-sm btn-outline-dark me-2">編輯 <i class="bi bi-pen"></i></a>
</td>
</tr>
<tr>
<td scope="row" class="ps-4">TX20220315190301</td>
<td>dog123@email.com</td>
<td>毛小熊</td>
<td>食品專賣店:熟食類</td>
<td><div class="text-muted">尚未付款</div></td>
<td class="text-end">2,200</td>
<td class="text-end pe-4">
<a href="#" class="btn btn-sm btn-outline-dark me-2">編輯 <i class="bi bi-pen"></i></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="card-footer bg-transparent py-3">
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-end mb-0">
<li class="page-item"><a class="page-link" href="#">Previous</a></li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
</nav>
</div>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="./javascripts/chart.js"></script>
<script src="./javascripts/all.js"></script>
</body>
</html>
// javascripts/all.js
const toggleMenuBtn = document.querySelector('#toggle-btn');
const body = document.querySelector('body');
toggleMenuBtn.addEventListener('click', (evt) => {
// console.log(evt);
evt.preventDefault();
body.classList.toggle('sidebar-toggled');
});
// javascripts/chart.js
// 動態圖表
(() => {
const chartColors = {
red: 'rgb(255, 99, 132)',
orange: 'rgb(255, 159, 64)',
yellow: 'rgb(255, 205, 86)',
green: 'rgb(75, 192, 192)',
blue: 'rgb(54, 162, 235)',
purple: 'rgb(153, 102, 255)',
grey: 'rgb(201, 203, 207)'
};
var randomScalingFactor = function () {
return Math.round(Math.random() * 2000000);
};
const pieCtx = document.getElementById('pie-chart').getContext('2d');
const barCtx = document.getElementById('bar-chart').getContext('2d');
const config = {
type: 'pie',
data: {
datasets: [{
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
chartColors.red,
chartColors.orange,
chartColors.yellow,
chartColors.green,
chartColors.blue,
],
label: 'Dataset 1'
}],
labels: [
'餅乾類',
'飲料類',
'熟食類',
'生鮮類',
'糖果類',
]
},
options: {
responsive: true
}
};
const barConfig = {
type: 'bar',
data: {
datasets: [{
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
chartColors.red,
chartColors.orange,
chartColors.yellow,
chartColors.green,
chartColors.blue,
chartColors.purple,
],
label: '單月營業額'
}],
labels: [
'一月',
'二月',
'三月',
'四月',
'五月',
'六月',
]
},
options: {
responsive: true
}
};
const pieChart = new Chart(pieCtx, config);
const barChart = new Chart(barCtx, barConfig);
})();
// javascripts/modal.js
// 互動視窗 Modal
const modalByDelete = document.querySelector('#deleteModal');
modalByDelete.addEventListener('show.bs.modal', function(event) {
const button = event.relatedTarget;
const orderId = button.dataset.bsOrderId;
// console.log(button, orderId);
const modalText = modalByDelete.querySelector('#deleteText');
modalText.textContent = orderId;
});
後台管理:單一產品頁面製作
// order.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 首頁</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body>
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end pt-3 d-flex bg-white flex-column">
<!-- 1. 後台名稱 -->
<div class="px-4">
<strong>食品專賣店</strong>
- 後台管理
</div>
<!-- 2. 選單 -->
<div class="overflow-auto mt-3">
<div>
<a href="home.html" class="sidebar-link">
<div class="px-4">
<i class="bi bi-house me-2"></i>
首頁
</div>
</a>
</div>
<div>
<a href="#menu-order" class="sidebar-link" data-bs-toggle="collapse">
<div class="d-flex justify-content-between px-4">
<p class="mb-0">
<i class="bi bi-card-checklist me-2"></i>
訂單管理
</p>
<i class="bi bi-caret-down"></i>
</div>
</a>
<div class="collapse" id="menu-order">
<a href="orders.html" class="sidebar-link">
<div class="ps-5">
訂單列表
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link active">
<div class="ps-5">
單一訂單細節
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
其他項目
</div>
</a>
</div>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-card-list me-2"></i>
產品列表
</div>
</a>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-list-stars me-2"></i>
顧客評價
</div>
</a>
</div>
</div>
<!-- 3. 登出按鈕 -->
<a href="#" class="mt-auto sidebar-link">
<div class="px-4">
<i class="bi bi-box-arrow-right me-2"></i>
登出
</div>
</a>
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom sticky-top">
<a href="#" class="d-inline-block py-3 px-4 border-end" id="toggle-btn">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
<div class="p-4">
<!-- 主要內容 -->
<div class="row">
<div class="col-lg-3 mb-3">
<div class="list-group sticky-top" style="top: 80px;">
<a href="#" class="list-group-item list-group-item-action active" aria-current="true">
摘要
</a>
<a href="#" class="list-group-item list-group-item-action">購買品項</a>
<a href="#" class="list-group-item list-group-item-action">發票管理</a>
<a href="#" class="list-group-item list-group-item-action">危險操作</a>
</div>
</div>
<div class="col-lg-9">
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</div>
</div>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
<script src="./javascripts/all.js"></script>
</body>
</html>
// helpers/_variables.scss
// List group
// scss-docs-start list-group-variables
$list-group-color: $gray-900 !default;
$list-group-bg: $white !default;
$list-group-border-color: rgba($black, .125) !default;
$list-group-border-width: $border-width !default;
$list-group-border-radius: $border-radius-lg; // $border-radius !default;
$list-group-item-padding-y: $spacer * .5 !default;
$list-group-item-padding-x: $spacer !default;
$list-group-item-bg-scale: -80% !default;
$list-group-item-color-scale: 40% !default;
$list-group-hover-bg: $gray-100 !default;
$list-group-active-color: $component-active-color !default;
$list-group-active-bg: $component-active-bg !default;
$list-group-active-border-color: $list-group-active-bg !default;
$list-group-disabled-color: $gray-600 !default;
$list-group-disabled-bg: $list-group-bg !default;
$list-group-action-color: $gray-700 !default;
$list-group-action-hover-color: $list-group-action-color !default;
$list-group-action-active-color: $body-color !default;
$list-group-action-active-bg: $gray-200 !default;
// scss-docs-end list-group-variables
後台管理:Sticky 與 scroll spy 的混合運用
// order.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>後台管理 - 單一訂單細節</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
</head>
<body data-bs-spy="scroll" data-bs-target="#detail-list-item" data-bs-offset="80">
<!-- 後台管理:結構規劃 start -->
<div class="d-flex">
<aside class="sidebar vh-100 border-end pt-3 d-flex bg-white flex-column">
<!-- 1. 後台名稱 -->
<div class="px-4">
<strong>食品專賣店</strong>
- 後台管理
</div>
<!-- 2. 選單 -->
<div class="overflow-auto mt-3">
<div>
<a href="home.html" class="sidebar-link">
<div class="px-4">
<i class="bi bi-house me-2"></i>
首頁
</div>
</a>
</div>
<div>
<a href="#menu-order" class="sidebar-link" data-bs-toggle="collapse">
<div class="d-flex justify-content-between px-4">
<p class="mb-0">
<i class="bi bi-card-checklist me-2"></i>
訂單管理
</p>
<i class="bi bi-caret-down"></i>
</div>
</a>
<div class="collapse" id="menu-order">
<a href="orders.html" class="sidebar-link">
<div class="ps-5">
訂單列表
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="order.html" class="sidebar-link active">
<div class="ps-5">
單一訂單細節
</div>
</a>
</div>
<div class="collapse" id="menu-order">
<a href="#" class="sidebar-link">
<div class="ps-5">
其他項目
</div>
</a>
</div>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-card-list me-2"></i>
產品列表
</div>
</a>
</div>
<div>
<a href="#" class="sidebar-link">
<div class="px-4">
<i class="bi bi-list-stars me-2"></i>
顧客評價
</div>
</a>
</div>
</div>
<!-- 3. 登出按鈕 -->
<a href="#" class="mt-auto sidebar-link">
<div class="px-4">
<i class="bi bi-box-arrow-right me-2"></i>
登出
</div>
</a>
</aside>
<main class="main">
<div class="bg-white w-100 border-bottom sticky-top">
<a href="#" class="d-inline-block py-3 px-4 border-end" id="toggle-btn">
<i class="bi bi-arrows-angle-expand"></i>
</a>
</div>
<div class="p-4">
<!-- 主要內容 -->
<div class="row">
<div class="col-lg-3 mb-3">
<nav id="detail-list-item" class="list-group sticky-top" style="top: 80px;">
<a href="#card-summary" class="list-group-item list-group-item-action active" aria-current="true">
摘要
</a>
<a href="#card-detail" class="list-group-item list-group-item-action">購買品項</a>
<a href="#card-invoice" class="list-group-item list-group-item-action">發票管理</a>
<a href="#card-danger" class="list-group-item list-group-item-action">危險操作</a>
</nav>
</div>
<div class="col-lg-9">
<div class="card mb-3">
<div class="card-header py-4" id="card-summary">
摘要
</div>
<div class="card-body">
<dl class="row mb-0">
<dt class="col-sm-3 text-truncate">訂單編號</dt>
<dd class="col-sm-9">TX20220315171601</dd>
<dt class="col-sm-3 text-truncate">訂單金額</dt>
<dd class="col-sm-9">600</dd>
<dt class="col-sm-3 text-truncate">訂單狀態</dt>
<dd class="col-sm-9">待處理</dd>
<dt class="col-sm 3 text-truncate">發票狀態</dt>
<dd class="col-sm-9">未開立</dd>
</dl>
</div>
</div>
<div class="card mb-3">
<div class="card-header py-4" id="card-detail">
購買品項
</div>
<div class="card-body p-0">
<table class="table table-hover mb-0 text-nowrap align-middle w-100" style="font-size: 14px;">
<thead class="bg-light">
<tr>
<th scope="col" class="py-3 ps-4 border-0"></th>
<th scope="col" class="py-3 border-0">貨號</th>
<th scope="col" class="py-3 border-0">商品名稱</th>
<th scope="col" class="py-3 border-0">購買價格</th>
<th scope="col" class="py-3 border-0">訂購數量</th>
<th scope="col" class="py-3 border-0">出貨狀態</th>
<th scope="col" class="py-3 pe-3 border-0">編輯</th>
</tr>
</thead>
<tbody class="text-nowrap">
<tr class="align-middle">
<td class="ps-4"><input type="checkbox" class="form-check-input"></td>
<td scope="row">P20220315171601</td>
<td>餅乾類</td>
<td>600</td>
<td>1</td>
<td class="text-muted">尚未處理</td>
<td class="text-center pe-3">
<div class="btn-group">
<button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">編輯</button>
<ul class="dropdown-menu">
<li><a href="#" class="dropdown-item">尚未處理</a></li>
<li><a href="#" class="dropdown-item">已出貨</a></li>
<li><a href="#" class="dropdown-item">已取貨</a></li>
<li><hr class="dropdown-divider"></li>
<li><a href="#" class="dropdown-item text-danger">刪除品項</a></li>
</ul>
</div>
</td>
</tr>
<tr class="align-middle">
<td class="ps-4"><input type="checkbox" class="form-check-input"></td>
<td scope="row">P20220315170201</td>
<td>飲料類</td>
<td>1,200</td>
<td>2</td>
<td class="text-muted">尚未處理</td>
<td class="text-center pe-3">
<div class="btn-group">
<button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">編輯</button>
<ul class="dropdown-menu">
<li><a href="#" class="dropdown-item">尚未處理</a></li>
<li><a href="#" class="dropdown-item">已出貨</a></li>
<li><a href="#" class="dropdown-item">已取貨</a></li>
<li><hr class="dropdown-divider"></li>
<li><a href="#" class="dropdown-item text-danger">刪除品項</a></li>
</ul>
</div>
</td>
</tr>
<tr class="align-middle">
<td class="ps-4"><input type="checkbox" class="form-check-input"></td>
<td scope="row">P20220315190301</td>
<td>熟食類</td>
<td>2,200</td>
<td>5</td>
<td class="text-muted">尚未處理</td>
<td class="text-center pe-3">
<div class="btn-group">
<button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">編輯</button>
<ul class="dropdown-menu">
<li><a href="#" class="dropdown-item">尚未處理</a></li>
<li><a href="#" class="dropdown-item">已出貨</a></li>
<li><a href="#" class="dropdown-item">已取貨</a></li>
<li><hr class="dropdown-divider"></li>
<li><a href="#" class="dropdown-item text-danger">刪除品項</a></li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
<div class="px-4 py-3">
<div class="btn-group">
<button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
出貨狀態管理
</button>
<ul class="dropdown-menu">
<li><a href="#" class="dropdown-item">尚未處理</a></li>
<li><a href="#" class="dropdown-item">已出貨</a></li>
<li><a href="#" class="dropdown-item">已取貨</a></li>
<li><hr class="dropdown-divider"></li>
<li><a href="#" class="dropdown-item text-danger">刪除品項</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-header py-4" id="card-invoice">
發票管理
</div>
<div class="card-body">
<div class="row mb-3">
<label for="invoiceType" class="col-sm-2 col-form-label">發票類型</label>
<div class="col-sm-10">
<select name="" id="invoiceType" class="form-select">
<option value="">個人發票</option>
<option value="">營業人三聯式發票</option>
<option value="">捐贈發票</option>
</select>
</div>
</div>
<div class="row mb-3">
<label for="taxNumber" class="col-sm-2 col-form-label">統一編號</label>
<div class="col-sm-10">
<input type="text" id="taxNumber" class="form-control" value="11223355">
</div>
</div>
<div class="row mb-3">
<label for="companyName" class="col-sm-2 col-form-label">公司名稱</label>
<div class="col-sm-10">
<input type="text" id="companyName" class="form-control" value="食品專賣店">
</div>
</div>
<div class="text-end">
<button type="button" class="btn btn-outline-primary">更多資訊</button>
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-header py-4" id="card-danger">
危險操作
</div>
<div class="card-body">
<div class="row align-items-center mb-3">
<div class="col-2">
<button type="button" class="btn btn-outline-secondary w-100">退款</button>
</div>
<div class="col">退還用戶款項</div>
</div>
<div class="row align-items-center mb-3">
<div class="col-2">
<button type="button" class="btn btn-outline-secondary w-100">折讓</button>
</div>
<div class="col">
針對已開立的訂單退回部分款項
</div>
</div>
<div class="row align-items-center mb-3">
<div class="col-2">
<button type="button" class="btn btn-outline-danger w-100">刪除訂單</button>
</div>
<div class="col">
將訂單刪除,並移除相關訂單資訊
</div>
</div>
</div>
</div>
<div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</div>
</div>
</div>
</div>
</main>
</div>
<!-- 後台管理:結構規劃 end -->
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
<script src="./javascripts/all.js"></script>
</body>
</html>
後台管理:作業製作
- 每個分頁都做完,上傳至 Google Drive, GitHub
- 只做一頁,把所有分頁集合在一起
後台管理:範例程式碼參考
注意:本章節提供 Codepen 範例程式碼,請勿直接複製,盡可能自行完成作業
製作作業時,請按照以下規則:
- 請調整其他顏色,與範例不同
- 請完成所有的功能 (包含所有表格的下拉選單)
- 可選擇多檔繳交 (需附上完整 Sass),或類似範例單一頁面繳交均可
CH14 – Landing Page 設計稿練習
Landing Page 設計稿練習:章節簡介
- Sketch
- Adobe XD
- Figma
個人練習採用的圖片
- Photo by Glenn Carstens-Peters
- White Shapes Free Stock Image
- Vector by pch.vector – 01
- Vector by pch.vector – 02
- Vector by pch.vector – 03
- Vector by pch.vector – 04
Landing Page 設計稿練習:課程資源
圖檔連結可參考影音課程。
Landing Page 設計稿練習:導覽列製作
// .gitignore
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
// stylesheets/all.scss
// Configuration
@import "../node_modules/bootstrap/scss/functions";
@import "./helpers/variables";
@import "../node_modules/bootstrap/scss/utilities";
@import "../node_modules/bootstrap/scss/mixins";
// Layout & components
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
@import "../node_modules/bootstrap/scss/transitions";
@import "../node_modules/bootstrap/scss/dropdown";
@import "../node_modules/bootstrap/scss/button-group";
@import "../node_modules/bootstrap/scss/nav";
@import "../node_modules/bootstrap/scss/navbar";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/accordion";
@import "../node_modules/bootstrap/scss/breadcrumb";
@import "../node_modules/bootstrap/scss/pagination";
@import "../node_modules/bootstrap/scss/badge";
@import "../node_modules/bootstrap/scss/alert";
@import "../node_modules/bootstrap/scss/progress";
@import "../node_modules/bootstrap/scss/list-group";
@import "../node_modules/bootstrap/scss/close";
@import "../node_modules/bootstrap/scss/toasts";
@import "../node_modules/bootstrap/scss/modal";
@import "../node_modules/bootstrap/scss/tooltip";
@import "../node_modules/bootstrap/scss/popover";
@import "../node_modules/bootstrap/scss/carousel";
@import "../node_modules/bootstrap/scss/spinners";
@import "../node_modules/bootstrap/scss/offcanvas";
@import "../node_modules/bootstrap/scss/placeholders";
// Helpers
@import "../node_modules/bootstrap/scss/helpers";
// Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
// index.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>接案家</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Noto Sans TC', sans-serif;
}
</style>
</head>
<body>
<!-- Landing Page 設計稿練習:導覽列製作 start -->
<nav class="navbar navbar-expand-lg navbar-light bg-white">
<div class="container">
<a class="navbar-brand" href="#"><i class="bi bi-house-fill text-info"></i> 接案家</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item mx-3">
<a class="nav-link active" aria-current="page" href="#">首頁</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">服務介紹</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">方案費用</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">常見問題</a>
</li>
<li class="nav-item">
<a class="btn btn-info" href="#">方案費用</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Landing Page 設計稿練習:導覽列製作 end -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>
// stylesheets/helpers/_variables.scss
// scss-docs-start navbar-theme-variables
$navbar-dark-color: rgba($white, .55) !default;
$navbar-dark-hover-color: rgba($white, .75) !default;
$navbar-dark-active-color: $white !default;
$navbar-dark-disabled-color: rgba($white, .25) !default;
$navbar-dark-toggler-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-dark-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>") !default;
$navbar-dark-toggler-border-color: rgba($white, .1) !default;
$navbar-light-color: rgba($black, .55) !default;
$navbar-light-hover-color: rgba($black, .7) !default;
$navbar-light-active-color: rgba($info, .9); // rgba($black, .9) !default;
$navbar-light-disabled-color: rgba($black, .3) !default;
$navbar-light-toggler-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-light-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>") !default;
$navbar-light-toggler-border-color: rgba($black, .1) !default;
$navbar-light-brand-color: $navbar-light-active-color !default;
$navbar-light-brand-hover-color: $navbar-light-active-color !default;
$navbar-dark-brand-color: $navbar-dark-active-color !default;
$navbar-dark-brand-hover-color: $navbar-dark-active-color !default;
// scss-docs-end navbar-theme-variables
Landing Page 設計稿練習:Header 圖片
開發過程中,設計稿桌面版、行動版一起觀看。
// index.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>接案家</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Noto Sans TC', sans-serif;
}
</style>
</head>
<body>
<!-- Landing Page 設計稿練習:導覽列製作 start -->
<nav class="navbar navbar-expand-lg navbar-light bg-white">
<div class="container">
<a class="navbar-brand" href="#"><i class="bi bi-house-fill text-info"></i> 接案家</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item mx-3">
<a class="nav-link active" aria-current="page" href="#">首頁</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">服務介紹</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">方案費用</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">常見問題</a>
</li>
<li class="nav-item">
<a class="btn btn-info" href="#">方案費用</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Landing Page 設計稿練習:導覽列製作 end -->
<!-- Landing Page 設計稿練習:Header 圖片 start -->
<header class="header px-4 py-5 d-flex align-items-lg-center justify-content-center" style="background-image: url(https://images.unsplash.com/photo-1497091071254-cc9b2ba7c48a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=874&q=80);">
<div class="text-white text-center">
<p class="fs-5">你是不是也有需要</p>
<h1 class="fw-bold">找個接案家?</h1>
<p>想有人幫你做網站開發、設計稿設計、程式編碼,<br>響應式排版、客戶使用者體驗!<br>提供店家在網路上,有更多機會讓更多人可以看到你的店家。</p>
</div>
</header>
<!-- Landing Page 設計稿練習:Header 圖片 end -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>
// stylesheets/components/_header.scss
.header {
height: 627px;
background-size: cover;
background-position: bottom center;
}
// stylesheets/all.scss
// Configuration
@import "../node_modules/bootstrap/scss/functions";
@import "./helpers/variables";
@import "../node_modules/bootstrap/scss/utilities";
@import "../node_modules/bootstrap/scss/mixins";
// Layout & components
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
@import "../node_modules/bootstrap/scss/transitions";
@import "../node_modules/bootstrap/scss/dropdown";
@import "../node_modules/bootstrap/scss/button-group";
@import "../node_modules/bootstrap/scss/nav";
@import "../node_modules/bootstrap/scss/navbar";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/accordion";
@import "../node_modules/bootstrap/scss/breadcrumb";
@import "../node_modules/bootstrap/scss/pagination";
@import "../node_modules/bootstrap/scss/badge";
@import "../node_modules/bootstrap/scss/alert";
@import "../node_modules/bootstrap/scss/progress";
@import "../node_modules/bootstrap/scss/list-group";
@import "../node_modules/bootstrap/scss/close";
@import "../node_modules/bootstrap/scss/toasts";
@import "../node_modules/bootstrap/scss/modal";
@import "../node_modules/bootstrap/scss/tooltip";
@import "../node_modules/bootstrap/scss/popover";
@import "../node_modules/bootstrap/scss/carousel";
@import "../node_modules/bootstrap/scss/spinners";
@import "../node_modules/bootstrap/scss/offcanvas";
@import "../node_modules/bootstrap/scss/placeholders";
// Helpers
@import "../node_modules/bootstrap/scss/helpers";
// Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
@import "./components/header";
Landing Page 設計稿練習:多欄式卡片
// index.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>接案家</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Noto Sans TC', sans-serif;
}
</style>
</head>
<body>
<!-- Landing Page 設計稿練習:導覽列製作 start -->
<nav class="navbar navbar-expand-lg navbar-light bg-white">
<div class="container">
<a class="navbar-brand" href="#"><i class="bi bi-house-fill text-info"></i> 接案家</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item mx-3">
<a class="nav-link active" aria-current="page" href="#">首頁</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">服務介紹</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">方案費用</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">常見問題</a>
</li>
<li class="nav-item">
<a class="btn btn-info" href="#">方案費用</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Landing Page 設計稿練習:導覽列製作 end -->
<!-- Landing Page 設計稿練習:Header 圖片 start -->
<header class="header px-4 py-5 d-flex align-items-lg-center justify-content-center" style="background-image: url(https://images.unsplash.com/photo-1497091071254-cc9b2ba7c48a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=874&q=80);">
<div class="text-white text-center">
<p class="fs-5">你是不是也有需要</p>
<h1 class="fw-bold">找個接案家?</h1>
<p>想有人幫你做網站開發、設計稿設計、程式編碼,<br>響應式排版、客戶使用者體驗!<br>提供店家在網路上,有更多機會讓更多人可以看到你的店家。</p>
</div>
</header>
<!-- Landing Page 設計稿練習:Header 圖片 end -->
<!-- Landing Page 設計稿練習:多欄式卡片 start -->
<section class="container my-5">
<div class="row flex-row-reverse">
<div class="col-lg-6 d-flex align-items-center">
<div>
<h2>讓我們幫你建立專屬的網站</h2>
<p class="lh-lg text-secondary">我們有專業的網頁工程師、網頁設計師,<br>也有新星、來自各地的專業人才,<br>幫您製作您心目中的樣式、版型。<br>讓你專注把心力花在你覺得更須優先的事情上!<br>(依專案內容報價、可行性是否接案)</p>
</div>
</div>
<div class="col-lg-6">
<img src="https://img.freepik.com/free-vector/cartoon-man-sitting-home-with-laptop_74855-6963.jpg?w=996&t=st=1647914030~exp=1647914630~hmac=31a82c3465d7d99f8f5f546e5b59a34f281c0a3512b6fa5d1d7555376cd43038" class="w-100" alt="">
</div>
</div>
</section>
<!-- Landing Page 設計稿練習:多欄式卡片 end -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>
Landing Page 設計稿練習:特殊卡片排版
// index.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>接案家</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Noto Sans TC', sans-serif;
}
</style>
</head>
<body>
<!-- Landing Page 設計稿練習:導覽列製作 start -->
<nav class="navbar navbar-expand-lg navbar-light bg-white">
<div class="container">
<a class="navbar-brand" href="#"><i class="bi bi-house-fill text-info"></i> 接案家</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item mx-3">
<a class="nav-link active" aria-current="page" href="#">首頁</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">服務介紹</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">方案費用</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">常見問題</a>
</li>
<li class="nav-item">
<a class="btn btn-info" href="#">方案費用</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Landing Page 設計稿練習:導覽列製作 end -->
<!-- Landing Page 設計稿練習:Header 圖片 start -->
<header class="header px-4 py-5 d-flex align-items-lg-center justify-content-center" style="background-image: url(https://images.unsplash.com/photo-1497091071254-cc9b2ba7c48a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=874&q=80);">
<div class="text-white text-center">
<p class="fs-5">你是不是也有需要</p>
<h1 class="fw-bold">找個接案家?</h1>
<p>想有人幫你做網站開發、設計稿設計、程式編碼,<br>響應式排版、客戶使用者體驗!<br>提供店家在網路上,有更多機會讓更多人可以看到你的店家。</p>
</div>
</header>
<!-- Landing Page 設計稿練習:Header 圖片 end -->
<!-- Landing Page 設計稿練習:多欄式卡片 start -->
<section class="container my-5">
<div class="row flex-row-reverse">
<div class="col-lg-6 d-flex align-items-center">
<div>
<h2>讓我們幫你建立專屬的網站</h2>
<p class="lh-lg text-secondary">我們有專業的網頁工程師、網頁設計師,<br>也有新星、來自各地的專業人才,<br>幫您製作您心目中的樣式、版型。<br>讓你專注把心力花在你覺得更須優先的事情上!<br>(依專案內容報價、可行性是否接案)</p>
</div>
</div>
<div class="col-lg-6">
<img src="https://img.freepik.com/free-vector/cartoon-man-sitting-home-with-laptop_74855-6963.jpg?w=996&t=st=1647914030~exp=1647914630~hmac=31a82c3465d7d99f8f5f546e5b59a34f281c0a3512b6fa5d1d7555376cd43038" class="w-100" alt="">
</div>
</div>
</section>
<!-- Landing Page 設計稿練習:多欄式卡片 end -->
<!-- Landing Page 設計稿練習:特殊卡片排版 start -->
<section class="py-5" style="background-image: url('https://cdn.stocksnap.io/img-thumbs/960w/white-shapes_HOGKNEMAUX.jpg'); background-size: cover;">
<div class="container">
<h2 class="text-center mb-4">你有這些需求嗎?</h2>
<div class="row row-cols-1 row-cols-lg-4 g-3 g-lg-4">
<div class="col">
<div class="card border-0 shadow">
<div class="card-body text-center py-4">
<i class="bi bi-vector-pen fs-s-48 text-info"></i>
<h3 class="h4">網頁設計</h3>
<p class="text-secondary card-text lh-lg">對於網頁設計稿,提供多種版型參考製作。</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow">
<div class="card-body text-center py-4">
<i class="bi bi-image fs-s-48 text-info"></i>
<h3 class="h4">圖片應用</h3>
<p class="text-secondary card-text lh-lg">擁有一堆店家相關的產品、活動,沒有地方可以使用。</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow">
<div class="card-body text-center py-4">
<i class="bi bi-code fs-s-48 text-info"></i>
<h3 class="h4">程式編碼</h3>
<p class="text-secondary card-text lh-lg">網頁設計搞切版,經由程式編碼成網頁畫面。</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow">
<div class="card-body text-center py-4">
<i class="bi bi-shop fs-s-48 text-info"></i>
<h3 class="h4">店家網站開發</h3>
<p class="text-secondary card-text lh-lg">屬於店家個人網站可以有更多的內容呈現給顧客。</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Landing Page 設計稿練習:特殊卡片排版 end -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>
// all.scss
// Configuration
@import "../node_modules/bootstrap/scss/functions";
@import "./helpers/variables";
@import "./helpers/utilities";
@import "../node_modules/bootstrap/scss/mixins";
// Layout & components
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
@import "../node_modules/bootstrap/scss/transitions";
@import "../node_modules/bootstrap/scss/dropdown";
@import "../node_modules/bootstrap/scss/button-group";
@import "../node_modules/bootstrap/scss/nav";
@import "../node_modules/bootstrap/scss/navbar";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/accordion";
@import "../node_modules/bootstrap/scss/breadcrumb";
@import "../node_modules/bootstrap/scss/pagination";
@import "../node_modules/bootstrap/scss/badge";
@import "../node_modules/bootstrap/scss/alert";
@import "../node_modules/bootstrap/scss/progress";
@import "../node_modules/bootstrap/scss/list-group";
@import "../node_modules/bootstrap/scss/close";
@import "../node_modules/bootstrap/scss/toasts";
@import "../node_modules/bootstrap/scss/modal";
@import "../node_modules/bootstrap/scss/tooltip";
@import "../node_modules/bootstrap/scss/popover";
@import "../node_modules/bootstrap/scss/carousel";
@import "../node_modules/bootstrap/scss/spinners";
@import "../node_modules/bootstrap/scss/offcanvas";
@import "../node_modules/bootstrap/scss/placeholders";
// Helpers
@import "../node_modules/bootstrap/scss/helpers";
// Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
@import "./components/header";
// stylesheets/helpers/_utilities.scss
// Text
// scss-docs-start utils-text
"font-family": (
property: font-family,
class: font,
values: (monospace: var(--#{$variable-prefix}font-monospace))
),
"font-size": (
rfs: true,
property: font-size,
class: fs,
values: $font-sizes
),
// custom
"font-size-static": (
rfs: true,
property: font-size,
class: fs-s,
values: (
48: 48px
)
),
"font-style": (
property: font-style,
class: fst,
values: italic normal
),
"font-weight": (
property: font-weight,
class: fw,
values: (
light: $font-weight-light,
lighter: $font-weight-lighter,
normal: $font-weight-normal,
bold: $font-weight-bold,
bolder: $font-weight-bolder
)
),
"line-height": (
property: line-height,
class: lh,
values: (
1: 1,
sm: $line-height-sm,
base: $line-height-base,
lg: $line-height-lg,
)
),
"text-align": (
responsive: true,
property: text-align,
class: text,
values: (
start: left,
end: right,
center: center,
)
),
"text-decoration": (
property: text-decoration,
values: none underline line-through
),
"text-transform": (
property: text-transform,
class: text,
values: lowercase uppercase capitalize
),
"white-space": (
property: white-space,
class: text,
values: (
wrap: normal,
nowrap: nowrap,
)
),
"word-wrap": (
property: word-wrap word-break,
class: text,
values: (break: break-word),
rtl: false
),
// scss-docs-end utils-text
Landing Page 設計稿練習:表單響應式卡片排版
// index.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>接案家</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Noto Sans TC', sans-serif;
}
</style>
</head>
<body>
<!-- Landing Page 設計稿練習:導覽列製作 start -->
<nav class="navbar navbar-expand-lg navbar-light bg-white">
<div class="container">
<a class="navbar-brand" href="#"><i class="bi bi-house-fill text-info"></i> <span style="color: #333333;">接案家</span></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item mx-3">
<a class="nav-link active" aria-current="page" href="#">首頁</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">服務介紹</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">方案費用</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="#">常見問題</a>
</li>
<li class="nav-item">
<a class="btn btn-info" href="#">方案費用</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Landing Page 設計稿練習:導覽列製作 end -->
<!-- Landing Page 設計稿練習:Header 圖片 start -->
<header class="header px-4 py-5 d-flex align-items-lg-center justify-content-center" style="background-image: url(https://images.unsplash.com/photo-1497091071254-cc9b2ba7c48a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=874&q=80);">
<div class="text-white text-center">
<p class="fs-5">你是不是也有需要</p>
<h1 class="fw-bold">找個接案家?</h1>
<p>想有人幫你做網站開發、設計稿設計、程式編碼,<br>響應式排版、客戶使用者體驗!<br>提供店家在網路上,有更多機會讓更多人可以看到你的店家。</p>
</div>
</header>
<!-- Landing Page 設計稿練習:Header 圖片 end -->
<!-- Landing Page 設計稿練習:多欄式卡片 start -->
<section class="container my-5">
<div class="row flex-row-reverse">
<div class="col-lg-6 d-flex align-items-center">
<div>
<h2>讓我們幫你建立專屬的網站</h2>
<p class="lh-lg text-secondary">我們有專業的網頁工程師、網頁設計師,<br>也有新星、來自各地的專業人才,<br>幫您製作您心目中的樣式、版型。<br>讓你專注把心力花在你覺得更須優先的事情上!<br>(依專案內容報價、可行性是否接案)</p>
</div>
</div>
<div class="col-lg-6">
<img src="https://img.freepik.com/free-vector/cartoon-man-sitting-home-with-laptop_74855-6963.jpg?w=996&t=st=1647914030~exp=1647914630~hmac=31a82c3465d7d99f8f5f546e5b59a34f281c0a3512b6fa5d1d7555376cd43038" class="w-100" alt="">
</div>
</div>
</section>
<!-- Landing Page 設計稿練習:多欄式卡片 end -->
<!-- Landing Page 設計稿練習:特殊卡片排版 start -->
<section class="py-5" style="background-image: url('https://cdn.stocksnap.io/img-thumbs/960w/white-shapes_HOGKNEMAUX.jpg'); background-size: cover;">
<div class="container">
<h2 class="text-center mb-4">你有這些需求嗎?</h2>
<div class="row row-cols-1 row-cols-lg-4 g-3 g-lg-4">
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4">
<i class="bi bi-vector-pen fs-s-48 text-info"></i>
<h3 class="h4">網頁設計</h3>
<p class="text-secondary card-text lh-lg">對於網頁設計稿,提供多種版型參考製作。</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4">
<i class="bi bi-image fs-s-48 text-info"></i>
<h3 class="h4">圖片應用</h3>
<p class="text-secondary card-text lh-lg">擁有一堆店家相關的產品、活動,沒有地方可以使用。</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4">
<i class="bi bi-code fs-s-48 text-info"></i>
<h3 class="h4">程式編碼</h3>
<p class="text-secondary card-text lh-lg">網頁設計搞切版,經由程式編碼成網頁畫面。</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4">
<i class="bi bi-shop fs-s-48 text-info"></i>
<h3 class="h4">店家網站開發</h3>
<p class="text-secondary card-text lh-lg">屬於店家個人網站可以有更多的內容呈現給顧客。</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Landing Page 設計稿練習:特殊卡片排版 end -->
<!-- Landing Page 設計稿練習:表單響應式卡片排版 start -->
<section class="py-5 container">
<h2 class="text-center mb-4">方案費用</h2>
<div class="row row-cols-1 row-cols-lg-3 g-3 g-lg-4">
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-header border-0 text-center text-secondary">
小小接案家
</div>
<div class="card-body text-center flex-grow-0">
<img src="https://img.freepik.com/free-vector/business-team-planning-working-process-flat-vector-illustration-cartoon-colleagues-talking-sharing-thoughts-smiling-company-office-teamwork-workflow-concept_74855-9813.jpg?w=826&t=st=1647914011~exp=1647914611~hmac=ff2fb348d4926011451bac062af4a3aa4c6a5e1bed69184b16748b972569d90f" class="img-fluid" style="height: 195px;" alt="">
<div class="text-info mt-3" style="height: 56px;">
NT <strong class="fs-1">1500</strong> /天
</div>
</div>
<ul class="list-group list-group-flush border-top border-bottom">
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 一天工作時間 4 小時
</li>
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 不接受急件
</li>
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 單一服務需求
</li>
</ul>
<div class="card-body d-flex">
<button type="button" class="btn btn-info w-100 align-self-end">選擇方案</button>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-header border-0 text-center bg-info text-white">
接一整天囉
</div>
<div class="card-body text-center flex-grow-0">
<img src="https://img.freepik.com/free-vector/company-employees-sharing-thoughts-ideas_74855-5469.jpg?w=826&t=st=1647914017~exp=1647914617~hmac=2b53174196afb7d52d3d7ea5fe1f954ee2909527859840e9930e8f16a6f7fa19" class="img-fluid" style="height: 195px;" alt="">
<div class="text-info mt-3" style="height: 56px;">
NT <strong class="fs-1">3500</strong> /天
</div>
</div>
<ul class="list-group list-group-flush border-top border-bottom">
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 一天工作時間 8 小時
</li>
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 不接受急件
</li>
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 多個服務提供
</li>
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 有問題可小部分修改
</li>
</ul>
<div class="card-body d-flex">
<button type="button" class="btn btn-info w-100 align-self-end">選擇方案</button>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-header border-0 text-center text-secondary">
盡心盡力的人生
</div>
<div class="card-body text-center flex-grow-0">
<img src="https://img.freepik.com/free-vector/customer-giving-quality-feedback_74855-5482.jpg?w=996&t=st=1647914023~exp=1647914623~hmac=c12d3dc02623204a0474a6c26a6782c6d5bc444e4478da5ddbfbf37de2cb7b07" class="img-fluid" style="height: 195px;" alt="">
<div class="text-info mt-3 fs-5 d-flex justify-content-center" style="height: 56px;">
<div class=" align-self-center">
客製化詢價
</div>
</div>
</div>
<ul class="list-group list-group-flush border-top border-bottom">
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 一系列的服務、完成,您交辦的客製化專案,歡迎與我們聯繫!
</li>
</ul>
<div class="card-body d-flex">
<button type="button" class="btn btn-info w-100 align-self-end">線上諮詢</button>
</div>
</div>
</div>
</div>
</section>
<!-- Landing Page 設計稿練習:表單響應式卡片排版 end -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>
討論區問題回答
.card-body 的部分加上 .flex-grow-0 就會改為依內容改變高度,因此兩個 .card-body 的文字大小不同造成高度有些微差異
在 .card-body 固定高度是可以的,也可以針對「客製化詢價」和「NT 666 / 月」設定相同的行高,讓內容的高度相等
Landing Page 設計稿練習:章節練習說明
自我練習製作
// index.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>接案家</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Noto Sans TC', sans-serif;
}
</style>
</head>
<body>
<!-- Landing Page 設計稿練習:導覽列製作 start -->
<nav class="navbar navbar-expand-lg navbar-light bg-white">
<div class="container">
<a class="navbar-brand" href="#"><i class="bi bi-house-fill text-info"></i> <span style="color: #333333;">接案家</span></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item mx-3">
<a class="nav-link active" aria-current="page" href="index.html">首頁</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="index.html#intro">服務介紹</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="index.html#plan">方案費用</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="qa.html">常見問題</a>
</li>
<li class="nav-item">
<a class="btn btn-info" href="#">方案購買</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Landing Page 設計稿練習:導覽列製作 end -->
<!-- Landing Page 設計稿練習:Header 圖片 start -->
<header class="header px-4 py-5 d-flex align-items-lg-center justify-content-center" style="background-image: url(https://images.unsplash.com/photo-1497091071254-cc9b2ba7c48a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=874&q=80);">
<div class="text-white text-center">
<p class="fs-5">你是不是也有需要</p>
<h1 class="fw-bold">找個接案家?</h1>
<p>想有人幫你做網站開發、設計稿設計、程式編碼,<br>響應式排版、客戶使用者體驗!<br>提供店家在網路上,有更多機會讓更多人可以看到你的店家。</p>
</div>
</header>
<!-- Landing Page 設計稿練習:Header 圖片 end -->
<!-- Landing Page 設計稿練習:多欄式卡片 start -->
<section class="container py-5" id="intro">
<div class="row flex-row-reverse">
<div class="col-lg-6 d-flex align-items-center">
<div>
<h2>讓我們幫你建立專屬的網站</h2>
<p class="lh-lg text-secondary">我們有專業的網頁工程師、網頁設計師,<br>也有新星、來自各地的專業人才,<br>幫您製作您心目中的樣式、版型。<br>讓你專注把心力花在你覺得更須優先的事情上!<br>(依專案內容報價、可行性是否接案)</p>
</div>
</div>
<div class="col-lg-6">
<img src="https://img.freepik.com/free-vector/cartoon-man-sitting-home-with-laptop_74855-6963.jpg?w=996&t=st=1647914030~exp=1647914630~hmac=31a82c3465d7d99f8f5f546e5b59a34f281c0a3512b6fa5d1d7555376cd43038" class="w-100" alt="">
</div>
</div>
</section>
<!-- Landing Page 設計稿練習:多欄式卡片 end -->
<!-- Landing Page 設計稿練習:特殊卡片排版 start -->
<section class="py-5" style="background-image: url('https://cdn.stocksnap.io/img-thumbs/960w/white-shapes_HOGKNEMAUX.jpg'); background-size: cover;">
<div class="container">
<h2 class="text-center mb-4">你有這些需求嗎?</h2>
<div class="row row-cols-1 row-cols-lg-4 g-3 g-lg-4">
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4">
<i class="bi bi-vector-pen fs-s-48 text-info"></i>
<h3 class="h4">網頁設計</h3>
<p class="text-secondary card-text lh-lg">對於網頁設計稿,提供多種版型參考製作。</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4">
<i class="bi bi-image fs-s-48 text-info"></i>
<h3 class="h4">圖片應用</h3>
<p class="text-secondary card-text lh-lg">擁有一堆店家相關的產品、活動,沒有地方可以使用。</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4">
<i class="bi bi-code fs-s-48 text-info"></i>
<h3 class="h4">程式編碼</h3>
<p class="text-secondary card-text lh-lg">網頁設計搞切版,經由程式編碼成網頁畫面。</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4">
<i class="bi bi-shop fs-s-48 text-info"></i>
<h3 class="h4">店家網站開發</h3>
<p class="text-secondary card-text lh-lg">屬於店家個人網站可以有更多的內容呈現給顧客。</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Landing Page 設計稿練習:特殊卡片排版 end -->
<!-- Landing Page 設計稿練習:表單響應式卡片排版 start -->
<section class="py-5 container" id="plan">
<h2 class="text-center mb-4">方案費用</h2>
<div class="row row-cols-1 row-cols-lg-3 g-3 g-lg-4">
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-header border-0 text-center text-secondary">
小小接案家
</div>
<div class="card-body text-center flex-grow-0">
<img src="https://img.freepik.com/free-vector/business-team-planning-working-process-flat-vector-illustration-cartoon-colleagues-talking-sharing-thoughts-smiling-company-office-teamwork-workflow-concept_74855-9813.jpg?w=826&t=st=1647914011~exp=1647914611~hmac=ff2fb348d4926011451bac062af4a3aa4c6a5e1bed69184b16748b972569d90f" class="img-fluid" style="height: 195px;" alt="">
<div class="text-info mt-3" style="height: 56px;">
NT <strong class="fs-1">1500</strong> /天
</div>
</div>
<ul class="list-group list-group-flush border-top border-bottom">
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 一天工作時間 4 小時
</li>
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 不接受急件
</li>
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 單一服務需求
</li>
</ul>
<div class="card-body d-flex">
<button type="button" class="btn btn-info w-100 align-self-end">選擇方案</button>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-header border-0 text-center bg-info text-white">
接一整天囉
</div>
<div class="card-body text-center flex-grow-0">
<img src="https://img.freepik.com/free-vector/company-employees-sharing-thoughts-ideas_74855-5469.jpg?w=826&t=st=1647914017~exp=1647914617~hmac=2b53174196afb7d52d3d7ea5fe1f954ee2909527859840e9930e8f16a6f7fa19" class="img-fluid" style="height: 195px;" alt="">
<div class="text-info mt-3" style="height: 56px;">
NT <strong class="fs-1">3500</strong> /天
</div>
</div>
<ul class="list-group list-group-flush border-top border-bottom">
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 一天工作時間 8 小時
</li>
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 不接受急件
</li>
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 多個服務提供
</li>
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 有問題可小部分修改
</li>
</ul>
<div class="card-body d-flex">
<button type="button" class="btn btn-info w-100 align-self-end">選擇方案</button>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow h-100">
<div class="card-header border-0 text-center text-secondary">
盡心盡力的人生
</div>
<div class="card-body text-center flex-grow-0">
<img src="https://img.freepik.com/free-vector/customer-giving-quality-feedback_74855-5482.jpg?w=996&t=st=1647914023~exp=1647914623~hmac=c12d3dc02623204a0474a6c26a6782c6d5bc444e4478da5ddbfbf37de2cb7b07" class="img-fluid" style="height: 195px;" alt="">
<div class="text-info mt-3 fs-5 d-flex justify-content-center" style="height: 56px;">
<div class=" align-self-center">
客製化詢價
</div>
</div>
</div>
<ul class="list-group list-group-flush border-top border-bottom">
<li class="list-group-item text-secondary ps-5">
<i class="bi bi-check-lg text-info position-absolute start-0 ms-3"></i> 一系列的服務、完成,您交辦的客製化專案,歡迎與我們聯繫!
</li>
</ul>
<div class="card-body d-flex">
<button type="button" class="btn btn-info w-100 align-self-end">線上諮詢</button>
</div>
</div>
</div>
</div>
</section>
<!-- Landing Page 設計稿練習:表單響應式卡片排版 end -->
<!-- 自行練習製作 練習和 footer start -->
<section class="py-5 container">
<h2 class="text-center mb-4">需要可以聯絡我們</h2>
<div class="row row-cols-1 row-cols-lg-3 g-3 g-lg-4 justify-content-center">
<div class="col-lg-3 col-9">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4 fs-4">
<a href="#" class="text-decoration-none link-dark stretched-link">
<i class="bi bi-telephone-fill text-info me-2"></i> 06-222-3333
</a>
</div>
</div>
</div>
<div class="col-lg-3 col-9">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4 fs-4">
<a href="#" class="text-decoration-none link-dark stretched-link">
<i class="bi bi-facebook text-info me-2"></i> 我就是個接案家
</a>
</div>
</div>
</div>
<div class="col-lg-3 col-9">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4 fs-4">
<a href="#" class="text-decoration-none link-dark stretched-link">
<i class="bi bi-question-lg text-info me-2"></i> 常見問題
</a>
</div>
</div>
</div>
</div>
</section>
<footer class="bg-secondary text-white py-4">
<div class="container">
<p class="text-center m-0">Copyright © 2022 接案家.All rights reserved.</p>
</div>
</footer>
<!-- 自行練習製作 練習和 footer end -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>
// qa.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>接案家</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Noto Sans TC', sans-serif;
}
</style>
</head>
<body>
<!-- Landing Page 設計稿練習:導覽列製作 start -->
<nav class="navbar navbar-expand-lg navbar-light bg-white">
<div class="container">
<a class="navbar-brand" href="#"><i class="bi bi-house-fill text-info"></i> <span style="color: #333333;">接案家</span></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item mx-3">
<a class="nav-link" href="index.html">首頁</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="index.html#intro">服務介紹</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="index.html#plan">方案費用</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link active" aria-current="page" href="qa.html">常見問題</a>
</li>
<li class="nav-item">
<a class="btn btn-info" href="#">方案購買</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Landing Page 設計稿練習:導覽列製作 end -->
<!-- 自行練習製作 Q&A start -->
<section class="py-5" style="background-image: url('https://cdn.stocksnap.io/img-thumbs/960w/white-shapes_HOGKNEMAUX.jpg'); background-size: cover;">
<div class="container">
<h3 class="text-center text-info fw-bold mb-1 fs-6">Q&A</h3>
<h2 class="text-center mb-4">常見問題</h2>
</div>
</section>
<section class="container py-5">
<div class="row justify-content-center">
<div class="col-lg-9">
<div class="accordion" id="accordionExample">
<div class="accordion-item">
<h2 class="accordion-header" id="headingOne">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
方案服務內容可以調整嗎?
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
<div class="accordion-body">
討論確定後,開始製作後只能小部分修改。太多修改部分,需另外加購方案天數。
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="headingTwo">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
小小接案家、接一整天囉兩者的差異?
</button>
</h2>
<div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="headingTwo" data-bs-parent="#accordionExample">
<div class="accordion-body">
小小接案家是一天工作時間為 4 小時。<br>
接一整天囉是一天工作時間為 8 小時。<br>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="headingThree">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
付款方式有哪些呢?
</button>
</h2>
<div id="collapseThree" class="accordion-collapse collapse" aria-labelledby="headingThree" data-bs-parent="#accordionExample">
<div class="accordion-body">
現金、轉帳為主,其他方式暫不支援。
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- 自行練習製作 Q&A end -->
<!-- 自行練習製作 聯絡和 footer start -->
<section class="py-5 container">
<h2 class="text-center mb-4">需要可以聯絡我們</h2>
<div class="row row-cols-1 row-cols-lg-3 g-3 g-lg-4 justify-content-center">
<div class="col-lg-3 col-9">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4 fs-4">
<a href="#" class="text-decoration-none link-dark stretched-link">
<i class="bi bi-telephone-fill text-info me-2"></i> 06-222-3333
</a>
</div>
</div>
</div>
<div class="col-lg-3 col-9">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4 fs-4">
<a href="#" class="text-decoration-none link-dark stretched-link">
<i class="bi bi-facebook text-info me-2"></i> 我就是個接案家
</a>
</div>
</div>
</div>
<div class="col-lg-3 col-9">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4 fs-4">
<a href="#" class="text-decoration-none link-dark stretched-link">
<i class="bi bi-question-lg text-info me-2"></i> 常見問題
</a>
</div>
</div>
</div>
</div>
</section>
<footer class="bg-secondary text-white py-4">
<div class="container">
<p class="text-center m-0">Copyright © 2022 接案家.All rights reserved.</p>
</div>
</footer>
<!-- 自行練習製作 聯絡和 footer end -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>
// stylesheets/helpers/_variables.scss
// scss-docs-start theme-color-variables
$primary: $blue !default;
$secondary: $gray-600 !default;
$success: $green !default;
$info: #4a6fa5; // $cyan !default;
$warning: $yellow !default;
$danger: $red !default;
$light: $gray-100 !default;
$dark: $gray-900 !default;
// scss-docs-end theme-color-variables
課程章節練習說明
// payment.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>接案家</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Noto Sans TC', sans-serif;
}
</style>
</head>
<body>
<!-- Landing Page 設計稿練習:導覽列製作 start -->
<nav class="navbar navbar-expand-lg navbar-light bg-white">
<div class="container">
<a class="navbar-brand" href="#"><i class="bi bi-house-fill text-info"></i> <span style="color: #333333;">接案家</span></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item mx-3">
<a class="nav-link" href="index.html">首頁</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="index.html#intro">服務介紹</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="index.html#plan">方案費用</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="qa.html">常見問題</a>
</li>
<li class="nav-item">
<a class="btn btn-info active" aria-current="page" href="payment.html">方案購買</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Landing Page 設計稿練習:導覽列製作 end -->
<section class="py-5" style="background-image: url('https://cdn.stocksnap.io/img-thumbs/960w/white-shapes_HOGKNEMAUX.jpg'); background-size: cover;">
<div class="container">
<h4 class="text-center text-info fw-bold">EXTRA EARN</h3>
<h2 class="text-center mb-4">開始找個接案家</h2>
</div>
</section>
<!-- Langing Page 設計稿練習:章節練習說明 start -->
<section class="py-5 container">
<div class="row justify-content-center">
<div class="col-lg-8">
<form action="" class="p-lg-5 shadow-lg">
<h3 class="deco-line mb-3">選擇方案</h3>
<div class="row row-cols-1 row-cols-lg-3">
<div class="col">
<button type="button" class="btn btn-outline-info w-100 btn-lg py-3 text-dark">
小小接案家<br class="d-none d-lg-block">
NT 1500 /天
</button>
</div>
<div class="col">
<button type="button" class="btn btn-outline-info w-100 btn-lg py-3 text-dark">
接一整天囉<br class="d-none d-lg-block">
NT 3500 /天
</button>
</div>
<div class="col">
<button type="button" class="btn btn-outline-info w-100 btn-lg py-3 text-dark active btn-special">
盡心盡力的人生<br class="d-none d-lg-block">
客製化詢價
</button>
</div>
</div>
</form>
</div>
</div>
</section>
<!-- Langing Page 設計稿練習:章節練習說明 end -->
<!-- 自行練習製作 練習和 footer start -->
<section class="py-5 container">
<h2 class="text-center mb-4">需要可以聯絡我們</h2>
<div class="row row-cols-1 row-cols-lg-3 g-3 g-lg-4 justify-content-center">
<div class="col-lg-3 col-9">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4 fs-4">
<a href="#" class="text-decoration-none link-dark stretched-link">
<i class="bi bi-telephone-fill text-info me-2"></i> 06-222-3333
</a>
</div>
</div>
</div>
<div class="col-lg-3 col-9">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4 fs-4">
<a href="#" class="text-decoration-none link-dark stretched-link">
<i class="bi bi-facebook text-info me-2"></i> 我就是個接案家
</a>
</div>
</div>
</div>
<div class="col-lg-3 col-9">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4 fs-4">
<a href="#" class="text-decoration-none link-dark stretched-link">
<i class="bi bi-question-lg text-info me-2"></i> 常見問題
</a>
</div>
</div>
</div>
</div>
</section>
<footer class="bg-secondary text-white py-4">
<div class="container">
<p class="text-center m-0">Copyright © 2022 接案家.All rights reserved.</p>
</div>
</footer>
<!-- 自行練習製作 練習和 footer end -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>
// stylesheet/helpers/_utilities.scss
// scss-docs-start utils-shadow
// shadow-lg(尺寸 → 中斷點)
"shadow": (
property: box-shadow,
class: shadow,
values: (
null: $box-shadow,
sm: $box-shadow-sm,
// lg: $box-shadow-lg,
none: none,
)
),
// scss-docs-end utils-shadow
// stylesheets/components/_deco-line.scss
.deco-line {
padding-left: 1rem;
position: relative;
&::after {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 3px;
background-color: $info;
}
}
& 直接把上面的 .deco-line 層級繼承過來。
// stylesheets/components/_custom-btn.scss
.btn-special {
&.active {
box-shadow: $box-shadow-sm;
}
}
// all.scss
// Configuration
@import "../node_modules/bootstrap/scss/functions";
@import "./helpers/variables";
@import "./helpers/utilities";
@import "../node_modules/bootstrap/scss/mixins";
// Layout & components
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
@import "../node_modules/bootstrap/scss/images";
@import "../node_modules/bootstrap/scss/containers";
@import "../node_modules/bootstrap/scss/grid";
@import "../node_modules/bootstrap/scss/tables";
@import "../node_modules/bootstrap/scss/forms";
@import "../node_modules/bootstrap/scss/buttons";
@import "../node_modules/bootstrap/scss/transitions";
@import "../node_modules/bootstrap/scss/dropdown";
@import "../node_modules/bootstrap/scss/button-group";
@import "../node_modules/bootstrap/scss/nav";
@import "../node_modules/bootstrap/scss/navbar";
@import "../node_modules/bootstrap/scss/card";
@import "../node_modules/bootstrap/scss/accordion";
@import "../node_modules/bootstrap/scss/breadcrumb";
@import "../node_modules/bootstrap/scss/pagination";
@import "../node_modules/bootstrap/scss/badge";
@import "../node_modules/bootstrap/scss/alert";
@import "../node_modules/bootstrap/scss/progress";
@import "../node_modules/bootstrap/scss/list-group";
@import "../node_modules/bootstrap/scss/close";
@import "../node_modules/bootstrap/scss/toasts";
@import "../node_modules/bootstrap/scss/modal";
@import "../node_modules/bootstrap/scss/tooltip";
@import "../node_modules/bootstrap/scss/popover";
@import "../node_modules/bootstrap/scss/carousel";
@import "../node_modules/bootstrap/scss/spinners";
@import "../node_modules/bootstrap/scss/offcanvas";
@import "../node_modules/bootstrap/scss/placeholders";
// Helpers
@import "../node_modules/bootstrap/scss/helpers";
// Utilities
@import "../node_modules/bootstrap/scss/utilities/api";
// Custom Components
@import "./components/header";
@import "./components/deco-line";
@import "./components/custom-btn";
自我練習製作
// payment.html
<!DOCTYPE html>
<html lang="zh-tw">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>接案家</title>
<link rel="stylesheet" href="./stylesheets/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Noto Sans TC', sans-serif;
}
</style>
</head>
<body>
<!-- Landing Page 設計稿練習:導覽列製作 start -->
<nav class="navbar navbar-expand-lg navbar-light bg-white">
<div class="container">
<a class="navbar-brand" href="#"><i class="bi bi-house-fill text-info"></i> <span style="color: #333333;">接案家</span></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item mx-3">
<a class="nav-link" href="index.html">首頁</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="index.html#intro">服務介紹</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="index.html#plan">方案費用</a>
</li>
<li class="nav-item mx-3">
<a class="nav-link" href="qa.html">常見問題</a>
</li>
<li class="nav-item">
<a class="btn btn-info active" aria-current="page" href="payment.html">方案購買</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Landing Page 設計稿練習:導覽列製作 end -->
<section class="py-5" style="background-image: url('https://cdn.stocksnap.io/img-thumbs/960w/white-shapes_HOGKNEMAUX.jpg'); background-size: cover;">
<div class="container">
<h4 class="text-center text-info fw-bold">EXTRA EARN</h3>
<h2 class="text-center mb-4">開始找個接案家</h2>
</div>
</section>
<!-- Langing Page 設計稿練習:章節練習說明 start -->
<section class="py-5 container">
<div class="row justify-content-center">
<div class="col-lg-8 shadow">
<form action="" class="p-lg-5 shadow-lg">
<h3 class="deco-line mb-3">選擇方案</h3>
<div class="row row-cols-1 row-cols-lg-3 g-2 mb-5">
<div class="col">
<button type="button" class="btn btn-outline-info w-100 btn-lg py-3 text-dark">
小小接案家<br class="d-none d-lg-block">
NT 1500 /天
</button>
</div>
<div class="col">
<button type="button" class="btn btn-outline-info w-100 btn-lg py-3 text-dark">
接一整天囉<br class="d-none d-lg-block">
NT 3500 /天
</button>
</div>
<div class="col">
<button type="button" class="btn btn-outline-info w-100 btn-lg py-3 text-white active btn-special">
盡心盡力的人生<br class="d-none d-lg-block">
客製化詢價
</button>
</div>
</div>
<!-- 自行練習製作 表單 start -->
<h3 class="deco-line mb-3">填寫資料</h3>
<div class="row g-3">
<div class="col-md-6">
<label for="inputText1" class="form-label">名字</label>
<input type="text" class="form-control" id="inputText1">
</div>
<div class="col-md-6">
<label for="inputText2" class="form-label">姓氏</label>
<input type="text" class="form-control" id="inputText2">
</div>
<div class="col-12">
<label for="inputTel1" class="form-label">手機號碼</label>
<input type="tel" class="form-control" id="inputTel1" placeholder="範例:0989-222-333">
</div>
<div class="col-12">
<label for="inputEmail1" class="form-label">電子郵件</label>
<input type="text" class="form-control" id="inputEmail1" placeholder="範例:receiver@gmail.com">
</div>
<div class="col-12">
<label for="inputAddress1" class="form-label">住址</label>
<input type="text" class="form-control" id="inputAddress1">
</div>
<div class="col-12">
<label for="inputTime" class="form-label">方便聯繫時間</label>
<select id="inputTime" class="form-select">
<option selected>13:00- 17:00</option>
<option>09:00-12:00</option>
</select>
</div>
<div class="col-12">
<label for="inputAddress2" class="form-label">住址</label>
<input type="text" class="form-control" id="inputAddress2">
</div>
<div class="col-12">
<div class="form-check p-0">
<label class="form-label">加購服務</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1">
<label class="form-check-label" for="inlineCheckbox1">設計諮詢 1 次</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="inlineCheckbox2" value="option2">
<label class="form-check-label" for="inlineCheckbox2">功能諮詢 1 次</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="inlineCheckbox3" value="option3">
<label class="form-check-label" for="inlineCheckbox3">錯誤諮詢 1 次</label>
</div>
</div>
<div class="col-12 mb-2">
<label for="exampleFormControlTextarea1" class="form-label">備註說明</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
<div class="col-12">
<button type="submit" class="btn btn-info w-100 py-2 text-dark">選擇方案</button>
</div>
</div>
<!-- 自行練習製作 表單 end -->
</form>
</div>
</div>
</section>
<!-- Langing Page 設計稿練習:章節練習說明 end -->
<!-- 自行練習製作 練習和 footer start -->
<section class="py-5 container">
<h2 class="text-center mb-4">需要可以聯絡我們</h2>
<div class="row row-cols-1 row-cols-lg-3 g-3 g-lg-4 justify-content-center">
<div class="col-lg-3 col-9">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4 fs-4">
<a href="#" class="text-decoration-none link-dark stretched-link">
<i class="bi bi-telephone-fill text-info me-2"></i> 06-222-3333
</a>
</div>
</div>
</div>
<div class="col-lg-3 col-9">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4 fs-4">
<a href="#" class="text-decoration-none link-dark stretched-link">
<i class="bi bi-facebook text-info me-2"></i> 我就是個接案家
</a>
</div>
</div>
</div>
<div class="col-lg-3 col-9">
<div class="card border-0 shadow h-100">
<div class="card-body text-center py-4 fs-4">
<a href="#" class="text-decoration-none link-dark stretched-link">
<i class="bi bi-question-lg text-info me-2"></i> 常見問題
</a>
</div>
</div>
</div>
</div>
</section>
<footer class="bg-secondary text-white py-4">
<div class="container">
<p class="text-center m-0">Copyright © 2022 接案家.All rights reserved.</p>
</div>
</footer>
<!-- 自行練習製作 練習和 footer end -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>