工程師都有google
的習慣,但是 bootstrap
的使用方式不用特別去估狗,基本的用法只要看官網的介紹就可以了。若發現自己看不懂文件,多半都是自己還沒有補足樣式相關的知識,建議相關的常識記得先補齊,也可以參考Day19的文章。
Bootstrap 的空間使用方式為距離、方向、量級的排列組合
內距p
、外距m
方向:上下左右、x軸、y軸、全方位
量級:0~5
, auto
我們以下列條件為前提做討論:
element.style {
display: flex;
flex-direction: row;
}
⭐️ 以flex-direction: row;
的前提下,水平相關的用法
<div class="d-flex justify-content-start">...</div>
<div class="d-flex justify-content-end">...</div>
<div class="d-flex justify-content-center">...</div>
<div class="d-flex justify-content-between">...</div>
<div class="d-flex justify-content-around">...</div>
⭐️ 以flex-direction: row;
的前提下,垂直相關的用法
<div class="d-flex align-items-start">...</div>
<div class="d-flex align-items-end">...</div>
<div class="d-flex align-items-center">...</div>
<div class="d-flex align-items-baseline">...</div>
<div class="d-flex align-items-stretch">...</div>
更多的 flex
用法可以參考官方
相信大家一定都知道 container,但大家知道 container
代表什麼意思嗎?我們來看誠品的網站,框起來的內容
container
指的是網頁的內容要被多少寬包覆,舉例來說當我們使用 <div class="container"><div>
以下 container
定義不一樣,但由於我們不需要做精細的響應式,會不會使用container
對後端工程師來說,差別可能不大。
<div class="container-sm">100% wide until small breakpoint</div>
<div class="container-md">100% wide until medium breakpoint</div>
<div class="container-lg">100% wide until large breakpoint</div>
<div class="container-xl">100% wide until extra large breakpoint</div>
<div class="container-xxl">100% wide until extra extra large breakpoint</div>
這是bootstrap
的網格系統,和Day19提到的 grid 用法差不多。
<div class="container">
<div class="row">
<div class="col-6">
內容
</div>
<div class="col-6">
內容
</div>
<div class="col-6">
內容
</div>
<div class="col-6">
內容
</div>
</div>
</div>
想必後端的朋友們,上述的排版方式應該再熟悉這個不過。對大部分後端來說,上述的排法就是前端實力的天花板 ? 。不過讀者們知道 grid 還可以做響應式嗎?只要搭配lg
, md
,就可以作出響應
<!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>
<!-- CSS only -->
<!-- https://getbootstrap.com/ -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x"
crossorigin="anonymous"
/>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-12 col-lg-6 border">內容</div>
<div class="col-12 col-lg-6 border">內容</div>
<div class="col-12 col-lg-8 border">內容</div>
<div class="col-12 col-lg-4 border">內容</div>
</div>
</div>
</body>
</html>
關於lg
, md
, xl
等尺寸表可以參考下方官網的表格。
Extra small <576px | Small ≥576px | Medium ≥768px | Large ≥992px | Extra large ≥1200px | |
---|---|---|---|---|---|
Max container width | None (auto) | 540px | 720px | 960px | 1140px |
Class prefix | .col- |
.col-sm- |
.col-md- |
.col-lg- |
.col-xl- |
# of columns | 12 | ||||
Gutter width | 30px (15px on each side of a column) | ||||
Nestable | Yes | ||||
Column ordering | Yes |
d-none
為display: none;
,但它絕對不是只有這麼簡單而已。當我們使用了這個屬性,我們可以玩很多響應式的東西,沿用上面的例子,我們來新增更多樣式
<!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>
<!-- CSS only -->
<!-- https://getbootstrap.com/ -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x"
crossorigin="anonymous"
/>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-12 col-lg-6 border">
<div class="d-none d-lg-block">
<a class="btn btn-primary" href="#" role="button">母訂單列表</a>
<a class="btn btn-primary" href="#" role="button">母訂單列表</a>
</div>
<div class="d-lg-none">
<a class="btn btn-primary" href="#" role="button">母湯</a>
<a class="btn btn-primary" href="#" role="button">母湯</a>
</div>
</div>
<div class="col-12 col-lg-6 border">
<div class="d-none d-lg-block">
<a class="btn btn btn-outline-secondary" href="#" role="button">母訂單列表</a>
<a class="btn btn btn-outline-secondary" href="#" role="button">母訂單列表</a>
</div>
<div class="d-lg-none">
<a class="btn btn btn-outline-secondary" href="#" role="button">母湯</a>
<a class="btn btn btn-outline-secondary" href="#" role="button">母湯</a>
</div>
</div>
<div class="col-12 col-lg-8 border">
<div class="col-12 col-lg-6 border">
<div class="d-none d-lg-block">
<a class="btn btn btn-outline-success" href="#" role="button">母訂單列表</a>
<a class="btn btn btn-outline-success" href="#" role="button">母訂單列表</a>
</div>
<div class="d-lg-none">
<a class="btn btn btn-outline-success" href="#" role="button">母湯</a>
<a class="btn btn btn-outline-success" href="#" role="button">母湯</a>
</div>
</div>
</div>
<div class="col-12 col-lg-4 border">
<div class="d-none d-lg-block">
<a class="btn btn btn-secondary" href="#" role="button">母訂單列表</a>
<a class="btn btn btn-secondary" href="#" role="button">母訂單列表</a>
</div>
<div class="d-lg-none">
<a class="btn btn btn-secondary" href="#" role="button">母湯</a>
<a class="btn btn btn-secondary" href="#" role="button">母湯</a>
</div>
</div>
</div>
</div>
</body>
</html>
我們可以利用d-none
搭配尺寸來去做響應式畫面,很好用 ?
bootstrap
對table
的支援相當高,光一個 table
就可以有好幾種變化型,官網就有很多用法可以參考,不過這篇想發想,如何讓table
按照自己的比例分配,可以使用網格系統的col
做搭配,理由如下:
table
排列屬性不為flex
,只用看得懂max-width
table
再過小尺寸時,讓它順其自然的發展也會比較好。table
thead
tr
th.col-2 商品品號
th.col-4 商品名稱
th.col-1 定價
th.col-1 售價
th.col-1 顏色
th.col-1 尺寸
th.col-1 數量
th.col-1
.col-2 {
flex: 0 0 16.66667%;
max-width: 16.66667%;
}
/* 對於table來說 */
.col-2 {
/* flex: 0 0 16.66667%; */
max-width: 16.66667%;
}
在講d-none
的時候已經講過了,此外官網也有專門講 button 的文章。以下為按鈕樣式的各種形式,而官網還特別介紹了顏色、屬性等一些很實用的技巧
<a class="btn btn-primary" href="#" role="button">Link</a>
<button class="btn btn-primary" type="submit">Button</button>
<input class="btn btn-primary" type="button" value="Input">
<input class="btn btn-primary" type="submit" value="Submit">
<input class="btn btn-primary" type="reset" value="Reset">
官網上的範例貼一貼,就有如上基本的頁籤樣式。曾經在前端客製化過頁籤,所以知道要打造好的頁籤不容易,但使用bootstrap
就不用擔心樣式的問題
<!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>
<!-- CSS only -->
<!-- https://getbootstrap.com/ -->
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
crossorigin="anonymous"
/>
</head>
<body>
<div class="container">
<button type="button" class="btn btn-primary my-2">
未出貨訂單 <span class="badge badge-light">4</span>
</button>
<button type="button" class="btn btn-primary my-2">
刷退失敗訂單 <span class="badge badge-light">5</span>
</button>
<button type="button" class="btn btn-primary my-2">
推播 <span class="badge badge-light">8</span>
</button>
</div>
</body>
</html>
後台介面,一定碰得到顯示數字的UI畫面,此時就可以使用badge
。
另外button
為行內元素,所以不能用區塊的概念控制,意即為使用margin
, padding
, flex
等等全部都會失效。
當我們要把多個輸入框併成群組時,可以使用input group
,
⭐️ 舉個例子
.form-group
label.col-md-2.control-label
| 選擇匯出日期
.col-md-10.col-lg-9
.input-daterange.input-group
input.input-md.form-control type="date" min="#{180.days.ago.to_date}" max="#{Date.today}" name="start_date" required="required" autocomplete="off"
span.input-group-addon 到
input.input-md.form-control type="date" max="#{Date.today}" name="end_date" required="required" autocomplete="off"
⭐️ 再舉一個例子
# 開始時間、結束時間模板
def search_interval(controller: nil, form: nil)
tag.div class: 'input-group mb-3' do
datatable_date_tag(controller: controller, target: 'startedAt', value: Date.today - 1.year, form: form) +
tag.div(class: 'input-group-append') { tag.label '至', class: 'input-group-text' } +
datatable_date_tag(controller: controller, target: 'endedAt', value: Date.today + 1.day, form: form)
end
end
⭐️ input_group
有 append
, prepend
兩個屬性可以調用
<!-- prepend -->
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">@</span>
</div>
<input type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1">
</div>
<!-- append -->
<div class="input-group mb-3">
<input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="basic-addon2">
<div class="input-group-append">
<span class="input-group-text" id="basic-addon2">@example.com</span>
</div>
</div>
⭐️ 搜尋輸入框,後面append
放大鏡
def datatable_search_field(options = {})
tag.div class: 'input-group mb-2', style: 'max-width: 300px' do
search_field_tag(options[:name], options[:placeholder], class: 'form-control', data: options[:data]) +
tag.div(class: 'input-group-append') do
tag.i class: 'fas fa-search input-group-text', style: 'padding-top: 10px'
end
end
end
至於如何用helper
使用,會在Day22
和大家交代清楚。請大家拭目以待
以下這些主題也很常被提及,讀者們當有機會從頭刻畫後台介面時,不妨可以看看
Day19粗略地提到了樣式的概念;今天粗略地提及了bootstrap
的使用方式。
各個公司可能會為了後台的美觀性,會購買市面上的主題,或者使用免費的sb-admin2
的主題製作。總之別人寫好的東西我們善加利用,基本的樣式技巧學好,便可以更融會貫通的應用!
覺得只用兩天的篇幅就講完樣式有點太少。日後在IT鐵人賽結束以前,如果有其他要補充的內容會另外修改文章,若讀者有什麼建議的也歡迎留言在下方。
下一篇會開始講Rails
附贈的helper
。