コーディングをする際、CSSのクラス命名に悩んでいたので、BEMというCSSの設計手法を只今勉強しておりますまっちーです。
今回はBEMで設計したSCSSファイルをgulpを使って自動でコンパイルする方法について、記して行きます。
BEMについて
BEMの概要
BEMとは、Block(かたまり)・Element(要素)・Modifier(修飾)の頭文字をとったものです。
Block | Element | Modifier | |
---|---|---|---|
説明 | 大きい括り | 大きい括りの中にある要素 | 状態 |
例 | header、 content、 footerなど | btn、img、textなど | current、大きさ、色など |
これらをつなげて以下のように書きます。
block__element--modifier
BlockとElementはアンダースコア2つ__で区切り, ElementとModifierはハイフン2つ—で区切ります。
少し長いクラス名になりますが、BEMを使うと、HTMLを見ただけでスタイルが予測しやすくなるなどのメリットがあります。
これなら命名に迷わないかも。でもクラス名が長いからcssに書くのが大変そう。。
Scssの書き方
CSSを効率的にかくための言語「Scss」を使うと、BEMは以下のように定義することができます。
.content{
background-colo:fff;
&__btn{
padding:20px 40px;
}
}
「&」とアンダースコア2つを組み合わせ「&__(Element)」と記述すると、CSSに下記のようにコンパイルされます。
.content {
background-color: #fff;
}
.content__btn {
padding: 20px 40px;
}
ネスト構造(入れ子)で&__を使えばシンプルに書ける!
BEMのディレクトリ構造
BEMのSCSSファイルは、1blockにつき1ファイルで作成するというルールがあり、複数ファイルに分割されます。ここではとにかくたくさんのscssファイルがたくさんある、ということを理解しておきます。
BEMのSCSSファイルのディレクトリ構造は以下の通り
scss
base
_base.scss
_reset.scss
mixin
(以下割愛)
module
page
pilgins
setting
style.css
index.htmlなどと同じ階層にあるscssディレクトリから、6つのディレクトリに分けられ、その中に、それぞれ_○○.scssファイルが格納されます。BEMの各ディレクトリの役割については下記のサイトを参照してください。
複数のscssファイルをgulpでコンパイルする
なぜgulpなのか
これまでSassのコンパイルはVisual Studio CodeのEasy Sassを使用していましたが、これを使うと、SCSSファイルごとにcssファイルが生成されてしまい、ファイル数が膨大になる問題がありました。
そこで、様々な「タスク」を自動化してくれるgulpが登場します。
gulpにはさまざまな用途がありますが、今回はgulpを使い「各ディレクトリに配置された複数のscssファイルを1つのstyle.scssファイルに読み込み、更新の都度、自動でstyle.cssファイルにコンパイルする」ことを目指します。
gulp・・・難しそうで避けていたけど・・やってみよう!
gulpをインストールしSassを自動でコンパイルする
インストールについては、こちらの記事がわかりやすかったです。
最終項の「watch機能を使えばファイルの更新後に自動で処理を実行できる」まで進めると下記のように自動でコンパイルされるようになります。
複数のscssファイルを1つのstyle.scssファイルに集約する
scssファイルが1つであれば、上記までの操作で自動コンパイルが使えるようになりますが、BEMは複数のscssファイルがあります。そのため各scssファイルを1つのstyle.scssファイルに集約します。
style.scssに下記のように定義することで、集約することができます。
@import "ファイル名";
この記述は簡単!でも_base.scssファイルを更新しても全然コンパイルされないなぁ・・
watch()メソッドの「監視するファイル」を変更する
現在のgulpfile.jsは下記の通りになっており、25行目に定義しているように、「css/style.scss」に変更があったときにコンパイルを実行するという処理になっています。
// gulpプラグインを読み込みます
const { src, dest, watch } = require("gulp");
// Sassをコンパイルするプラグインを読み込みます
const sass = require("gulp-sass")(require("sass"));
/**
* Sassをコンパイルするタスクです
*/
const compileSass = () =>
// style.scssファイルを取得
src("css/style.scss")
// Sassのコンパイルを実行
.pipe(
// コンパイル後のCSSを展開
sass({
outputStyle: "expanded"
})
)
// cssフォルダー以下に保存
.pipe(dest("css"));
/**
* Sassファイルを監視し、変更があったらSassを変換します
*/
const watchSassFiles = () => watch("css/style.scss", compileSass);
// npx gulpというコマンドを実行した時、watchSassFilesが実行されるようにします
exports.default = watchSassFiles;
しかしながら、実際にコードを入力し更新していくファイルはcss/style.scssではなく、css/○○/_○○.scssであるため、25行目のwatch()メソッドの監視するファイル名を変更します。
ファイル名は以下の様に記述をするととってもシンプルになります。
特定のディレクトリ直下にある全てのファイルとディレクトリを扱いたい場合は、アスタリスク2つとスラッシュ、その後ろにアスタリスク1つをつけて指定します。逆にアスタリスクを文字列に置き換えれば、そのファイルだけが監視されるという設定にも出来ます。
https://youki-takemoto.net/archives/106 「Youki Takemoto’s Blog」
"css/**/*.scss"
上記のように定義することで、cssディレクトリ以下の全てのscssファイルが変更された時にコンパイルされるようになります。
まとめると25行目は以下のコードになります。
const watchSassFiles = () => watch("css/**/*.scss", compileSass);
gulpを実行する
gulpを実行する際はコマンドラインでnpx gulp
と入力しENTERを押します。
npx gulp
css/base/_base.scssに記述した内容がcss/style.scssにインポートされ、css/stye.cssにコンパイルされるようになりました!
うおおおおお!
gulpがうまく動かない時は、Ctrl + cを押して実行中のコマンドを強制終了し、再びnpx gulpと入力すると動くことがあります。
久しぶりにgulpを使おうと思ったら以下のエラーが
Error in plugin "gulp-sass"
Message:
gulp-sass no longer has a default Sass compiler; please set one yourself.
Both the "sass" and "node-sass" packages are permitted.
For example, in your gulpfile:
const sass = require('gulp-sass')(require('sass'));
上記記事を参考に「sass」をインストールします。
npm i -D sass
無事使えるようになりました。
終わり
gulpを使うことでBEMのSCSSファイルを自動でコンパイルすることができました。BEMなどのクラス命名規則を学び、読めやすい、修正しやすいCSS が設計できるように頑張ります。
gulpって「一気に飲む」っていう意味らしい。まさに!
最後までお読みいただきありがとうございました。