クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【Sass(SCSS)】@importでBEMのBlockごとにファイル分割する

メタ言語の続きです。前回はBEMによるclass名をSass(SCSS)とEJSに書いてみました。今回からはモジュール設計に入ります。まずはBEMのB(ブロック)ごとにSass(SCSS)ファイルを分割してみます。@importを使います。それでは行きましょう!

【目次】

※参考:【メタ言語】BEMによるclass名をSass(SCSS)とEJSで書いてみる(モジュール事始め) - クモのようにコツコツと

※メタ言語(HTMLテンプレートエンジン、AltCSS、AltJS)まとめ
qiita.com

BEMによるCSS設計

BEMによるCSS設計、こちらのスライドがわかりやすくて参考になる!

Sass(SCSS)ファイルはブロックごとにファイルを分けるのがセオリーのようだが、その理由はブロックがファイル名になることによって、ブロックの重複が防げると!ファインダーのファイル一覧がブロック一覧わけだ!

そのほかにも参考になる記事がたくさん。少しずつ理解して進めて行きたく。

※参考:BEMをSassで快適に書く方法 | maesblog

※参考:一番詳しいCSS設計規則BEMのマニュアル - Qiita

※参考:SCSSのファイル設計について Vol.1 | 吉本式BEM設計(BEM設計ベース)

※参考:SCSSのファイル設計について Vol.2 | 吉本式BEM設計(BEM設計ベース)

※参考:SCSSのファイル設計(BEM設計からFLOCSS設計に) | 吉本式 Web制作のコーディングガイドライン

まずはブロックごとのファイル分割から取り組む!

common.css(ファイル分割前)

前回、こんな感じでBEM構成を作った。

f:id:idr_zz:20200521184358j:plain

common.scss

.main__lede {
  font-size: 0.8em;
}

.inner {
  background: #fff;
  padding: 20px;
  margin: 0 0 20px;
  &__title {
    color: purple;
    font-size: 1.5em;
    line-height: 1.2;
    }
   &__text {
    &-em {
      font-weight: bold;
      color: brown;
    }
    &-bikou {
    font-size: 0.8em;
    &:before {
        content: "※";
      }
    }
    &-btn {
      background: brown;
      color: #fff;
      padding: 10px;
    }  
  }

詳細は前回記事参照

※参考:【メタ言語】BEMによるclass名をSass(SCSS)とEJSで書いてみる(モジュール事始め) - クモのようにコツコツと

other.cssの内容を.mainに反映

ファイル名を「common.scss」を「style.scss」に変更した。最終的に書き出されるファイルは一つなので「共通」よりも「スタイル全体」みたいな意味がいいかなと思い。

Sass(SCSS)コンパイルの時にh1タグだけ「other.scss」に書いた。

#scss h1 {
  color: red;
  font-size: 2em;
}

※参考:【Gulp】watch()メソッドでSass(SCSS)を自動コンパイル - クモのようにコツコツと

その内容を.mainブロックに統合する。

.main {
  &__title {
    color: red;
    font-size: 2em;
  }
  &__lede {
    font-size: 0.8em;
  }
}

.inner {
  // 中略
}

.mainの中に&でネスト(入れ子)にした。

@importでパーシャルファイルをインポート

_main.scss作成

ファイル名にアンダースコア_を付けるとSassのコンパイルから除外される。これを「パーシャル」ファイルという。

ブロック関係は「block」というフォルダを作ってその中に入れることにする。まずは「_main.scss」を作る。

block/_main.scss

.main {
  &__title {
    color: red;
    font-size: 2em;
  }
  &__lede {
    font-size: 0.8em;
  }
}

_inner.scss作成

次に「_inner.scss」を作る。

block/_inner.scss

.inner {
    background: #fff;
    padding: 20px;
    margin: 0 0 20px;
    &__title {
      color: purple;
      font-size: 1.5em;
      line-height: 1.2;
      }
     &__text {
      &-em {
        font-weight: bold;
        color: brown;
      }
      &-bikou {
      font-size: 0.8em;
      &:before {
          content: "※";
        }
      }
      &-btn {
        background: brown;
        color: #fff;
        padding: 10px;
      }  
    }
  }

@importでstyle.scssにインポート

で、これを親階層の「style.scss」に@importでインポートする。

style.scss

@import 'block/_main';
@import 'block/_inner';

ほとんど内容が無いようw

この状態でgulpを起動してみると…

npx gulp

お、ブラウザが立ち上がった。 f:id:idr_zz:20200501053631j:plain スタイルもちゃんと当たっている!

コンパイルされたstyle.css

こうなった!

@charset "UTF-8";
.main__title {
  color: red;
  font-size: 2em;
}

.main__lede {
  font-size: 0.8em;
}

.inner {
  background: #fff;
  padding: 20px;
  margin: 0 0 20px;
}

.inner__title {
  color: purple;
  font-size: 1.5em;
  line-height: 1.2;
}

.inner__text-em {
  font-weight: bold;
  color: brown;
}

.inner__text-bikou {
  font-size: 0.8em;
}

.inner__text-bikou:before {
  content: "※";
}

.inner__text-btn {
  background: brown;
  color: #fff;
  padding: 10px;
}

@importで書いた順番にコンパイルされている!

パーシャルを修正してもコンパイルに反映されない!

下層の全ディレクトリを扱う(/**)

しかしこのままでは問題があった…。

gulpを起動した直後はパーシャルファイルをインポートしてコンパイルされるのだが、その後にパーシャルを修正しても、うんともすんとも言わない。

こちらの記事が参考になった!

特定のディレクトリ直下にある全てのファイルとディレクトリを扱いたい場合は、アスタリスク2つとスラッシュ、その後ろにアスタリスク1つをつけて指定します。

ディレクトリ名/**/*.scss

※参考:Gulpで複数ディレクトリのSCSSを自動コンパイルする方法! | Youki Takemoto's Blog

この書き方はSass(SCSS)に限らずワイルドカードの一般的な書き方のようだ。知らなかった!

gulpfile.jsを修正

「gulpfile.js」の中のSass(SCSS)関係のパスを書き換える。

Sassコンパイル部分

// sassコンパイル
gulp.task('sass', (done) => {
    gulp.src('./src/scss/**/*.scss')
        .pipe(sass({
                    outputStyle: 'expanded'
                })
            )
        .on("error", sass.logError)
        .pipe(gulp.dest('./dest/css'));
    done();
});

watch部分

// 監視ファイル
gulp.task('watch-files', (done) =>  {
    // 中略
    gulp.watch("./src/scss/**/*.scss", gulp.task('sass'));
    gulp.watch("./dest/css/*.css", gulp.task('browser-reload'));
    // 中略
    done();
});

実はここに至るまで色々エラーが出たり、再インストール、プラグインなど試行錯誤した。最終的には上記のコードで解決できた!

gulp再起動

gulpfile.jsの変更はNodeサーバを再起動しないと反映されないので一旦「Control + C」で閉じる。

gulp起動!

npx gulp

これでパーシャルファイルを修正した時もリアルタイムでブラウザが自動リロードされる!

ブログっぽいCSSに改造

ということでこの状態でSass(SCSS)のスタイルを改造してみた。 f:id:idr_zz:20200522182239j:plain 当ブログっぽいデザインにしてみた!

「_bass.scss」を作成

まず、「base」というフォルダを作って、中に「_base.scss」を作成。

base/_base.scss

body {
    margin: 0;
    padding: 0;
    font-family: sans-serif;
    color: #333;
    a {
        color: #C30D23;
    }
}

ここにはbodyタグなど全体に共通するスタイルを入れてみた。aタグに当ブログと同じアクセントカラー。

「style.scss」で「_base.scss」をインポート

それをstyle.scssにインポートする。

/***** base *****/
@import 'base/_base';


/***** block *****/
@import 'block/_main';
@import 'block/_inner';

境目がわかりやすいようにコメントも追加した。

「_main.scss」を修正

「_main.scss」の内容

/* main */
.main {
    width: 960px;
    margin: 0 auto;
    &__title {
      color: #333;
      font-size: 2em;
    }
    &__lede {
      font-size: 1em;
    }
  }

タイトルの背景を薄いグレーにし、左線にアクセントカラー。

「_inner.scss」を修正

「_inner.scss」の内容

/* inner */
.inner {
    margin: 0 0 40px;
    &__title {
      padding: 10px;
      background: #eee;
      border-left: 2px solid #C30D23;
      font-size: 1.5em;
      line-height: 1.2;
      }
     &__text {
      &-em {
        font-weight: bold;
        background: #eee;
        padding: 5px;
        color: #C30D23;
      }
      &-bikou {
      font-size: 0.8em;
      &:before {
          content: "※";
        }
      }
      &-btn {
        background: #C30D23;
        color: #fff;
        padding: 10px;
      }  
    }
  }

emとボタンにアクセントカラーを入れてみた。

コンパイルされた「style.css」

意図通りにコンパイルされた!

@charset "UTF-8";
/***** base *****/
body {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
  color: #333;
}

body a {
  color: #C30D23;
}

/***** block *****/
/* main */
.main {
  width: 960px;
  margin: 0 auto;
}

.main__title {
  color: #333;
  font-size: 2em;
}

.main__lede {
  font-size: 1em;
}

/* inner */
.inner {
  margin: 0 0 40px;
}

.inner__title {
  padding: 10px;
  background: #eee;
  border-left: 2px solid #C30D23;
  font-size: 1.5em;
  line-height: 1.2;
}

.inner__text-em {
  font-weight: bold;
  background: #eee;
  padding: 5px;
  color: #C30D23;
}

.inner__text-bikou {
  font-size: 0.8em;
}

.inner__text-bikou:before {
  content: "※";
}

.inner__text-btn {
  background: #C30D23;
  color: #fff;
  padding: 10px;
}

ファイル構成

「src/scss」フォルダの最終的な構成

f:id:idr_zz:20200522192252j:plain

  • scssフォルダ直下にstyle.scssがある
  • scssフォルダの下層にbaseフォルダ、blockフォルダがある
  • baseフォルダの中に_base.scssがある
  • blockフォルダの中にmain.scss、inner.scssがある

おまけ:@importは将来的になくなる!?

Sassの公式サイトで@importの情報が見つけにくいと思ったら…

※参考:Sass: Sass Basics

なんと!@importは将来的に廃止される予定なんだとか!

@useと@forwardという2つのルールが登場し、@importルールは将来的に廃止される予定です。

@importルールがかかえる多くの問題があります。ファイルスコープがないため依存モジュールの把握が困難になったり、名前空間を持たないためにライブラリの作者と利用者が命名を工夫しないといけなかったり

※参考:Sassの新しいモジュールシステム - シフトブレイン/スタンダードデザインユニット

@import自体がまだ使い始めたばかりで不便さを感じる前段階なのだがw

@use@forwardの書き方、使い分け方などもおいおいチェックして行きたく思う。

最後に

f:id:idr_zz:20200522182239j:plain

やってみた感想は、全体が1ファイルのCSSよりもモジュールがファイル分割されている方が修正箇所を探しやすい!

あと、ブロックを超えてページ全体に共通するアクセントカラーなどは変数化したくなってきた。モジュール分割した状態での変数の設定方法は次回以降にまた調べたく思います。@mixinとかを使うのかな?

それではまた!


※メタ言語(HTMLテンプレートエンジン、AltCSS、AltJS)まとめ
qiita.com