Bootstrap 是一個 Twitter 推出的 CSS 框架,也是我第一個使用的 CSS 框架。本文使用最新版本 v4.0.0-alpha.6,透過閱讀完整的源代碼,我們能夠更加了解 Bootstrap 的優缺點,以及如何自製 Bootstrap 輪子。

為什麼使用Bootstrap

透過使用Bootstrap框架,我們可以提高開發效率,避免重複製造輪子。

閱讀本文所需知識

  1. 一顆好奇心
  2. 基本Bootstrap知識
  3. 基本SCSS/SASS知識

Bootstrap4 的新特性

對比起Bootstrap3,Bootstrap4作出不少改動,以下是當中比較影響大的特性:

  1. 默認使用Flexbox
  2. 使用flexbox重新製作navbar,提高可塑性和客製化能力。
  3. .card代替.panel以及.well
  4. 能夠適應五種長度: xs, sm, md, lg, xl
  5. 更加大的默認字體: 16px
  6. 不再自帶Glyphicons圖案包。。。
  7. 使用SCSS開發

Bootstarp 源碼結構

bootstrap/  #v4-dev branch
├── build/
├── dist/ # 預先編譯的CSS
│   ├── css/
│   └── js/
├── docs/ # 文檔
    └── examples/ # 官方例子
├── js/
    ├── dist/
    ├── src/
    └── tests/
├── nuget/
└── scss/ # 本文開始入手的地方
    ├── mixins/
    └── utilities/

Bootstrap Grid架構

Bootstrap使用container->row->col-*-number的架構。

利用SCSS理解 Container

_grid.scss的一開始代碼段落中,我們可以看到.container, .fluid-container這兩個容器。如果 $enable-grid-classes是true的話,就可以使用.container以及.fluid-container

@if $enable-grid-classes {
  .container {
    @include make-container();
    @include make-container-max-widths();
  }
}

@if $enable-grid-classes {
  .container-fluid {
    width: 100%;
    @include make-container();
  }
}

理解Row

@if $enable-grid-classes {
  @include make-row();
  // 省略 .no-gutters
}

用到的函式 (mixins)

container

make-container (grid.scss)

它們會調用mixins/_grid.scss 裡面的@mixin make-container以及@mixin make-container-max-widths

@mixin make-container($gutters: $grid-gutter-widths) {
  margin-right: auto;
  margin-left: auto;

  @each $breakpoint in map-keys($gutters) {
    @include media-breakpoint-up($breakpoint) {
      $gutter: map-get($gutters, $breakpoint);
      padding-right: ($gutter / 2);
      padding-left:  ($gutter / 2);
    }
  }
}

map-get則是Sass裡面的一個函數,輸入一個map以及key,如果map裡面有該key的話,就會返回key的值。找不到的話就會返回null。

$grid-gutter-widths (variables.scss)

如果沒有設置$gutters,它就會默認是$grid-gutter-widths,以下是$grid-gutter-widths的包含的數值: xs, sm, md, lg, xl。

$grid-gutter-width-base:     30px !default;
$grid-gutter-widths: (
  xs: $grid-gutter-width-base, // 30px
  sm: $grid-gutter-width-base, // 30px
  md: $grid-gutter-width-base, // 30px
  lg: $grid-gutter-width-base, // 30px
  xl: $grid-gutter-width-base  // 30px
) !default;

$grid-breakpoints (variables.scss)

$grid-breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px
) !default;

它定義不同設備的屏幕寬度,用於響應式設計(Responsive Web Design)。

media-breakpoint-up (breakpoints.scss)

而media-breakpoint-up則是在mixins/_breakpoints.scss 第54行,用處是返回最短寬度的內容。

@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
  $min: breakpoint-min($name, $breakpoints);
  @if $min {
    @media (min-width: $min) {
      @content;
    }
  } @else {
    @content;
  }
}

breakpoint-min()

breakpoint-min()可以在mixins/_breakpoints.scss 第26行找到,它的用處是返回最短斷點寬度或者null。

@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
  $min: map-get($breakpoints, $name);
  @return if($min != 0, $min, null);
}

row

make-row() (grid.scss)

@mixin make-row($gutters: $grid-gutter-widths) {
  display: flex;
  flex-wrap: wrap;

  @each $breakpoint in map-keys($gutters) {
    @include media-breakpoint-up($breakpoint) {
      $gutter: map-get($gutters, $breakpoint);
      margin-right: ($gutter / -2);
      margin-left:  ($gutter / -2);
    }
  }
}

至於Column,我們下次再說吧。。。

如果你覺得我的文章對你有幫助的話,希望可以推薦和交流一下。歡迎關注和 Star 本博客或者關注我的 Github