既存環境にBootstrap4のGridを追加する

既存環境の新規LP作成にあたりCSSフレームワークである ` Bootstrap4(4.1.3)` のグリッド（flexbox）部分を取り出して仕様に合わせカスタマイズしたときの設定を公開
※実作業は、1年以上前の為Bootstrapのバージョンアップにより修正が必要なところがでているかもしれません。

## bootstrap4
- https://getbootstrap.com/docs/4.1/getting-started/download/

- Sassのソースからgrid(flex-box)部分のみ切り出し、ブレイクボイント及びgutterをカスタマイズして利用

- `main-grid.css` 
 - グリッド（flexbox）とそのヘルパークラスで構成。
 - Bootstrap4のグリッドを利用したいLP上で `main-grid.css` を読み込む


### CSS
```
/src/html/css/bootstrap4/main-grid.css　// bootstrapのgridフレームワーク本体(コンパイルされたもの)
```

### SCSS
```
/bootstrap4
  - main-grid.scss   // bootstrapのgridフレームワーク本体（こちらで作成したもの。他をimport管理している）
  - _functions.scss　// bootstrapのmixinsで利用される関数
  - _variables.scss　// bootstrapのmixinsで利用される変数

  - mixins/
   - _breakpoints.scss　       // bootstrapのmediaqueryのmixins
   - _grid-flex.scss           // bootstrapのgrid作成用のmixins（こちらで作成したもの）
   - _grid-framework.scss    // bootstrapのgrid作成用のmixins
   - _grid.scss                      // bootstrapのgrid作成用のmixins

  - utilities/
   - _display.scss　　　      // display関連のヘルパークラス
   - _flex.scss　　　　　　 // flex-box関連のヘルパークラス
```

```main-grid.scss
/*
 Grid variables
 bootstrapをimportする前に記述
*/

$grid-columns: 12;
$grid-gutter-width: 24px;

$grid-breakpoints:(
  xs: 0,     // 0 - 719.98px
  md: 720px, // 720px - 899.98px
  lg: 900px, // 900px以上
);

$container-max-widths: (
  lg: 1280px,
);

// reset
@at-root {
  @-ms-viewport { width: device-width; } // stylelint-disable-line at-rule-no-vendor-prefix
}

//bootstrap読み込み
@import "../bootstrap4/functions";
@import "../bootstrap4/variables";

@import "../bootstrap4/mixins/breakpoints";
@import "../bootstrap4/mixins/grid-framework";
@import "../bootstrap4/mixins/grid";
@import "../bootstrap4/mixins/grid-flex";

// ヘルパークラスの利用を #global-contents配下に限定
#global-contents {
	@import "../bootstrap4/utilities/display";
	@import "../bootstrap4/utilities/flex";
}

/* _grid.scss を基に作成 */

// Container widths
// Set the container width, and override it for fixed navbars in media queries.

@if $enable-grid-classes {
  .flex-container {
    @include make-flex-container();

    // Larger than lg:900px
    @include media-breakpoint-up(lg) {
      @include make-container-max-widths();
    }
  }
}

// Fluid container
//
// Utilizes the mixin meant for fixed width containers, but with 100% width for
// fluid, full width layouts.

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

// Row
//
// Rows contain and clear the floats of your columns.

@if $enable-grid-classes {
  .flex-container,
  .flex-container-fluid {
    .row {
      @include make-flex-row($grid-gutter-width);
      @include media-breakpoint-down(xs){
        @include make-flex-row(16px);
        > .col,
        > [class*="col-"] {
          padding-right: 8px;
          padding-left: 8px;
        }
      }

    // Remove the negative margin from default .row, then the horizontal padding
    // from all immediate children columns (to prevent runaway style inheritance).
    .no-gutters {
      margin-right: 0;
      margin-left: 0;

      > .col,
      > [class*="col-"] {
        padding-right: 0;
        padding-left: 0;
      }
    }
   }
  }
}

// Columns
//
// Common styles for small and large grid columns
@if $enable-grid-classes {
  .flex-container, .flex-container-fluid {
    @include make-grid-columns();
  }
}
```

```_grid-flex.scss
@charset "UTF-8";

/// Grid system
//
// Generate semantic grid columns with these mixins.

/*
 based mixin make-container()
 .flex-container 内で利用
*/

@mixin make-flex-container() {
  width: 100%;
  padding-right: 0;
  padding-left: 0;
  margin-right: auto;
  margin-left: auto;
}

/*
 based mixin make-row() 
 .flex-container .row内で利用
*/
@mixin make-flex-row($grid-gutter-width) {
  display: flex;
  flex-wrap: wrap;
  margin-right: ($grid-gutter-width / -2);
  margin-left: ($grid-gutter-width / -2);
}
```

### Variables 
`main-grid.scss` 内で `_variables.scss` で定義されている *!default* を上書きしている 

- $grid-breakpoints (ブレイクポイント)
   - xs (Small) : `0`  // 0px ~ 719.98px
   - md (Medium) : `720px`  // 720px ~ 899.98px
   - lg (Large) : `900px`  // 900px ~

- $grid-columns (グリッドのカラム数) :  `12`

- $grid-gutter-width (グリッド間の溝)
 - xs (Small) : `16px` (8px * 2)
 - md (Medium) /  lg (Large) : `24px`  (12px * 2)

- $container-max-widths (コンテナの最大幅)
 - lg (Large) : `1280px`

- コンテナの両サイドのマージン(フレームワーク外のLP側のSCSSで設定した)
  - xs (Small) : `15px` 
  - md (Medium) / lg (Large) : `16px`

### 使い方
- Grid system
 - https://getbootstrap.com/docs/4.1/layout/grid/
 - https://getbootstrap.com/docs/4.1/examples/grid/

- Display ユーティリティ
 - https://getbootstrap.com/docs/4.1/utilities/display/

- Flex ユーティリティ
 - https://getbootstrap.com/docs/4.1/utilities/flex/

### 参考 : 
- Bootstrapのグリッドシステムの使い方を初心者に向けておさらいする
 - http://websae.net/twitter-bootstrap-grid-system-21060224/

```html
<div class="flex-container">
	<div class="row">
		<div class="col-12 col-md-6 col-lg-3">
			1
		</div>
		<div class="col-12 col-md-6 col-lg-3">
			2
		</div>
		<div class="col-12 col-md-6 col-lg-3">
			3
		</div>
		<div class="col-12 col-md-6 col-lg-3">
			4
		</div>
	</div>
</div>
```

Bootstrapのクラスを利用することにより1行のカラム数  `12` をブレイクポイントごとにいくつずつ割り振るかをクラスで管理できる


#### ラッパークラス
この中に `.row` `col-*` を入れる

- `flex-container` 
   - Bootstrap4がデフォルトで指定している `.container` のクラスは既に使用されていたためクラス名を修正
   - lg (Large) 以上でコンテナの最大幅が有効になる。

- `flex-container-fluid` 
   - コンテナの最大幅の制限がないクラス

#### *行(横)*
- `.row`

この中に `col-*` を入れる。

#### *列(縦)*
- `col-*`
 - col- `ブレイクポイント`  `グリッドカラム数`

#### *例*

![grid_bs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99478/6320819a-5222-4500-22d6-0f1eec713139.png)

`col-12`  :  グリッド12すべての幅を使用する
`col-md-6` :  md(medium: 720px ~ 899.98px) 時カラム6つ分を使用する
`col-lg-3` : lg(Large : 900px ~)時に　カラム3つ分を使用する

この場合 ブレイクポイントがクラス名に入っていない `col-12` は `0~719px` で有効になる。

## gulp
- `node-sass` `postcss(+ autoprefixer)` を利用してコンパイルする必要があったため、タスクを追加。
- `package.json` `gulpfile.js` を更新

```javascript:gulp.js
+ // Bootstrap4用
+ var nodesass   = require('gulp-sass');
+ var sourcemaps = require('gulp-sourcemaps');
+ var postcss = require('gulp-postcss');
+ var autoprefixer = require('autoprefixer');

var src = {
+  bootstrap: root + 'bootstrap4/',

var filepath = {
+  bootstrap: src.bootstrap + '**/*.scss',

+ // Bootstrap4用 
+ // node-sass
+ gulp.task("nodesass",function(){
+     gulp.src(filepath.bootstrap)
+         .pipe(plumber({
+           errorHandler: notify.onError("Error: <%= error.message %>") //<-
+         }))
+         .pipe(sourcemaps.init())
+         .pipe(nodesass({outputStyle: 'compressed'}).on('error', nodesass.logError))
+         .pipe(postcss([
+             autoprefixer({browsers: ["last 3 versions", 'iOS >= 8.1', 'Android >= 4.3', "ie >= 9", "OperaMini all"]})
+          ]))
+         .pipe(sourcemaps.write())
+         .pipe(gulp.dest(dir.css + 'bootstrap4/'))
+         .pipe(browserSync.reload({stream: true}));
+ });

// Watch Tasks
+ gulp.task('default', ['nodesass','browser-sync'], function(){
+    gulp.watch(filepath.bootstrap, ['nodesass']);
```

### 新たにpackage.jsonに追加したライブラリ

- gulp-sass
 - sassのコンパイラ（node-sassをgulp上で使えるようにしたもの）
- gulp-postcss
 - CSSをパースしてAST(Abstract Syntax Tree、JSオブジェクト)を操作するAPIを提供する
- autoprefixer
 - Can I Use.のデータを基にブラウザバージョンを指定してベンダープレフィックスの自動付与を行う（postcssプラグイン）
- gulp-sourcemaps
 - ソースマップの出力を行う。（書き出されたCSSファイルからSCSS上の記述位置がわかる）	

```json:package.json
  "devDependencies": {
+   "autoprefixer": "^8.6.5",
+   "gulp-postcss": "^7.0.1",
+   "gulp-sass": "^3.2.1",
+   "gulp-sourcemaps": "^2.6.4",
  }
```