bootstrap4.3をscssから使ってポートフォリオサイトを作った

#はじめに
[bootstrapをhtmlで使う](https://qiita.com/takaaki-iwamoto/items/05e51441cc748df8ecb9)、[cssで使い分ける](https://qiita.com/takaaki-iwamoto/items/05e51441cc748df8ecb9)、とやってきたので次はsassだということでやってみました。

コードとしては相当問題がありそうなので、指摘くださればありがたいです。

とりあえず成果物のリンクです。
[完成品（サイト）](https://iwamoto-takaaki.github.io/bootstrap-and-scss-profile/)
[ソースコード](https://github.com/iwamoto-takaaki/bootstrap-and-scss-profile)
[CSS(前回)](https://github.com/iwamoto-takaaki/bootstrap-and-css-profile/blob/master/css/style.css)と[SCSS（今回)](https://github.com/iwamoto-takaaki/bootstrap-and-scss-profile/blob/master/scss/style.scss)　※diffが用意できませんでした。

あと、ビルドにgulpを使ったのですが、いつの間にか3.9から4.0にアップデートされていて、数日前に組んだビルドスクリプトが動かなくてハマりました。

追記-もともと、bootstrap4.2でやっていたのですが、xssのセキュリティ対策のupdateがあったらしく4.3にバージョンアップしました。font-sizeをレスポンシブに調整するmixinがバンドルされていて、ちょうど使うべき部分もありますが、紹介できるタイミングがあればということにします。

#方針

- HTMLのClassをすっきりさせる
- できるだけまともなscssを書こう
- bootstrapのmixinを積極的に使おう
- ~~_variables.scssを変更しよう~~（適用するネタが思いつかなかった）
- gulpでスマートにビルドしよう

#内容

## 環境構築

### npm

Node.jsとnpmはインストールされているものとします。（無い方はそれぞれインストール方法を調べてください。）

package.jsonを作ってもろもろインストールします。
（gulpが初めてでない方はgulp-cli(2行目)は不要です）

```
npm init 
npm install gulp-cli -g
npm install gulp -D
npm install bootstrap -D
npm install gulp-sass gulp-autoprefixer -D
npm install coffeescript -D
```

### git(.gitignore)

gitを使う場合は、.gitignoreに次の行を追加して、npmでダウンロードしたファイルを管理対象から除外します。

``` .gitignore
/node_modules/*
```

### gulpfile

gulpfileは拡張子を.coffeeとするだけでcoffesriptとして書くことができます。

```gulpfile.coffee
gulp = require 'gulp'
sass = require 'gulp-sass'
autoprefixer = require 'gulp-autoprefixer'

src = './scss/*.scss'
dest = './css/'

gulp.task 'build:scss', ->
  gulp.src src, {base: './scss/'}
  .pipe(sass({includePaths:['node_modules/bootstrap/scss']}))
  .pipe(autoprefixer())   # ベンダープレフィックスの付与
  .pipe sass { 
    outputStyle: 'expanded' }
  #  outputStyle: 'compact' }
  .pipe gulp.dest(dest)

gulp.task 'watch:scss', ->
  gulp.watch src, gulp.task('build:scss')

exports.default = gulp.series ['build:scss']

gulp.task 'watch', gulp.parallel('watch:scss')
```
build:scssというタスクは、scssフォルダにあるコードをcssに書き出すというコードです。
[bootstrap本体への参照を与えています](https://qiita.com/tanakahb/items/e912d469b7f598d66a12)ので、scssフォルダにはbootstrap全体を持って来る必要がありません。
autoprefixerはベンダープレフィックスを与えてくれるモジュールで[本家bootstrapのビルドでも使われているよう](https://qiita.com/tonkotsuboy_com/items/564f9bb78d177483f83e)です。

あと、gulp4からタスクの登録の方法が変わっていたことに気づかず結構な時間を無駄にしました、

## scssフォルダの設定
cssからbootstrapを利用する場合はhtmlの方にbootstrapへの参照を記述していました。sassの場合scss/style.scssに@importで記述すると出力先であるcss/style.cssにbootstrap.cssと同様のコードが展開されます。

```scss:style.scss
// bootstrapをインポートしておく
@import "bootstrap";
// 続く・・・
```

今回は、bootstrapの設定ファイルである_variables.scssを変更することで、細かい設定が変更できます。

_variables.scssを変更する場合は、node_modules/bootstrap/scssからscssにコピーして変更します。
(node_modules/bootstrap/scssは、今回はgitで管理しない設定なので直接設定したときには管理されません。)

変更できる内容は非常に多岐にわたり、説明できるほど把握できていませんが、例えばこのようなものです。

- カラーパレット
- ブレイクポイント(略称も）
- gridの分割数(標準は12分割）
- 各種コントロールの詳細
- その他

今回、style.scssで設定した点もいくつかは_variables.scssを変更することで対応できたかもしれません。詳しく知りたい方は、検索してみるとwebで編集してくれるサイトなどあります。

## sassって便利

bootstrapとは関係なくsassは便利という話です。

```css:style.css
.section-title{
    margin-bottom: 2rem;
    text-align: center;
}

.section-title .underbar{
    width: 6rem;
    height: 0.5rem;
    margin-right: auto;
    margin-left: auto;
    background-color: #4DF59B;
}
```

例えば、cssで書くとこのようなコードがscssに替えるとこのようになります。

```scss:style.scss
.section-title {
    margin-bottom: 2rem;
    text-align: center;
    .underbar {
        width: 6rem;
        height: 0.5rem;
        margin-right: auto;
        margin-left: auto;
        background-color: #4DF59B;
    }
}
```
セレクタを入れ子にできて、htmlのタグの配置との対応がわかり易くなります。

また、レスポンシブデザインも簡略化されます。

```css:style.css
@media (min-width: 1140px){
    #myname{
        font-size: 3rem;
    }
}

@media (min-width: 540px){
    #myname{
        font-size: 2rem;
    }
}

#myname{
    font-size: 1.2rem;
}
```

これを書き直すと

```scss:style.scss
#myname {
    font-size: 1.2rem;

    @media (min-width: 540px){
        font-size: 2rem;
    }
    @media (min-width: 1140px){
        font-size: 3rem;
    }
}
```

ずいぶんすっきりしました。とはいえ、画面サイズ毎に別ファイルに書きたいという人もあると思いますのでスキズキでしょうね。

##sassでbootstrapのレスポンシブデザインの使い方
先ほど、セレクタの中にメディアクエリを書けることを説明しました。bootstrapではブレイクポイントを定数で管理されています。直接ブレイクポイントを書き込むと変更漏れなどの不具合につながる可能性があるので、定数を使うことにします。

```scss:style.scss
#myname {
    font-size: 1.2rem;
    // レスポンシブデザイン周りはこんな感じ
    @include media-breakpoint-up('md'){
        font-size: 2rem;
    }
    @include media-breakpoint-up('lg'){
        font-size: 3rem;
    }
}
```

記述量が多くてちょっと面倒ですが、ブレイクポイントの名称を利用でき直接数字を入れるより影響が少なくなります。
ちなみに、画面サイズが小さい方を標準の書式に設定しているのは、画面サイズが小さいデバイスは描画能力が貧弱なため優先的に負荷を下げるためで、bootstrapはそのように組まれているらしいです。

##gridのscssでの使い方
先ほどの例をグリッドに応用するとこうなります。

```scss:style.scss
.card {
    padding: 0;
    //col-12 
    @include make-col(12);
    //col-sm-4
    @include media-breakpoint-up('sm'){
        @include make-col(4);
    }
}
```

cssでは、htmlにcol-sm-4が残っていましたがscssではhtmlをすっきりさせることができます。(記述量が・・・)

## bootstrapのmixinの探し方・使い方
scssから使うのはmixinを中心に使うということは判りましたが、実のところマニュアルが無い(あったらコメントを！)のでソースを読むしかありません。実際、css/scssが判っているならソースはそれ程難しくありません。
ただし、それなりの量があるので、がっつりマスターするつもりがない場合は、頭から読むのではなく関連するプロパティ名でgrepすると上手く見つかったりしました。

#感想
まず、Sassの話ですが、scssの@includeって長ったらしくて嫌いです。次はsass記法で書きます。そもそも私は、cssも慣れていないのでそのまま書けるメリットはあまり感じていないというのがあります。
bootstrapのmixinはそれなりに便利そうですが、憶えるのが面倒なのもあり、私の場合は慣れてきたら独自実装をしそうな気がします。とはいえ、sassの使い方としてはすごく参考になるのでソースはしっかり読み込んでおきたいです。

感想、コメントお待ちします。
とくに、こう書いたらいいんでは、という指摘があると嬉しいです。