Day20. 懂Bootstrap,并让Bootstrap带你上天堂

工程师都有google的习惯,但是 bootstrap 的使用方式不用特别去估狗,基本的用法只要看官网的介绍就可以了。若发现自己看不懂文件,多半都是自己还没有补足样式相关的知识,建议相关的常识记得先补齐,也可以参考Day19的文章。

Spacing: margin & padding

Bootstrap 的空间使用方式为距离、方向、量级的排列组合

  • 内距p、外距m

  • 方向:上下左右、x轴、y轴、全方位

  • 量级:0~5, auto

基本概念可以查看Day19,而如何使用可以查看 官方

flex

我们以下列条件为前提做讨论:

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 代表什麽意思吗?我们来看诚品的网站,框起来的内容

https://ithelp.ithome.com.tw/upload/images/20210916/20115854J5xVLHns5u.png

container 指的是网页的内容要被多少宽包覆,举例来说当我们使用 <div class="container"><div>

  • 浏览器宽度大於等於1400px ➡️ 1320px
  • 浏览器宽度大於等於1200px ➡️ 1140px
  • 浏览器宽度大於等於992px ➡️ 960px
  • 浏览器宽度大於等於768px ➡️ 720px
  • 浏览器宽度大於等於576px ➡️ 540px
  • 浏览器宽度小於576px ➡️ 满版。

以下 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>

grid

这是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/[email protected]/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

d-nonedisplay: 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/[email protected]/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 搭配尺寸来去做响应式画面,很好用 ?

table

bootstraptable的支援相当高,光一个 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%;
}

button

在讲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">

Tab

官网上的范例贴一贴,就有如上基本的页签样式。曾经在前端客制化过页签,所以知道要打造好的页签不容易,但使用bootstrap就不用担心样式的问题

badge

<!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>

https://ithelp.ithome.com.tw/upload/images/20210916/20115854spCMrrLies.png

後台介面,一定碰得到显示数字的UI画面,此时就可以使用badge

另外button 为行内元素,所以不能用区块的概念控制,意即为使用margin, padding, flex 等等全部都会失效。

Input group

当我们要把多个输入框并成群组时,可以使用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"

https://ithelp.ithome.com.tw/upload/images/20210913/20115854Gt0YqQ8tNE.png

⭐️ 再举一个例子

# 开始时间、结束时间模板
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_groupappend, 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


<<:  DAY5 Python基础教学(二)

>>:  19. Cookie/ LocalStorage/ SessionStorage 的差别

[Day11]程序菜鸟自学C++资料结构演算法 – 伫 列Queue

前言:上一篇结束了堆叠的实作,今天要来介绍新东西「伫列」。 伫列的特性:伫列和堆叠非常类似,同样都是...

[iT铁人赛Day5]JAVA的优先顺序

上次优先顺序还没讲,今天就来讲解一下 数学的运算符号有优先顺序的差别,JAVA也有 数学符号无疑是加...

Auto ML简介

前面提到的两个范例, 一个是MNiST手写辨识, 一个是心血管疾病的应用, 处理这两个范例的过程中大...

未完!待续?-金鱼都能懂的Bootstrap5网页框架开发

Bootstrap已是目前全球被大量网页开发者使用的一个网页UI框架了,其特色在於使用简单,开发快速...

[Angular] Day24. Template-driven forms

在上一篇中提到了 Angular 中的两种不同的 Form,介绍了他们在使用上以及细节上的不同,接着...