このウェブサイトのSassファイル群はずっとフラットなファイル構成でやっていた。主にSassが相対パスの修正を行うことができないことが理由だったけど、最近はポストプロセスすればどうにでも出来そうな感じなので、あまり気にせず整理することにした。単純にカテゴリ分けするだけでも良いのだけど、BEMを応用してやってみている。
CSSのクラス名及び変数やプレースホルダー・クラスにはまだ手を付けず、まずはBEMツリーとルールセットの配置の対応を作るところから始めた。
&を使ったセレクターのネストでモディファイア以上のようなルール付けの元にやってる(未完成)。
scss/ ├ _header.scss └ header/ ├ _logo.scss └ _site-navigation.scss
ファイル名がブロックになり、かつ繰り返しにならないようにディレクトリを使って配置する。CSSのクラス名で.header__site-navigationになるであろうルールセットが含まれるのがheader/_site-navigation.scssになる。必要なら必要なだけネストしていけば良い。例えば.header__site-navigationにナビゲーションのリスト以外に検索ボックスやRSSフィードを表示するブロックがあるなら以下のようにする。
scss/
├ _header.scss
└ header/
├ _logo.scss
├ _site-navigation.scss
└ site-navigation/
├ _feed.scss
├ _list.scss
└ _searchbox.scss
header/と_header.scssあるのはちょっと気持ち悪いし、ブロック単位での一括削除がしづらくなるので、header/_index.scssとかの方が良いのかもしれない。
body > header nav {
ul {
display: inline-table;
}
li {
display: table-cell;
}
}
ルールセット内で1段階ネストするとエレメントになる。先述のようにブロックは必ずファイルになるので、&を使わないネストは必ずエレメントとすることができ、読みやすくなる。
ブロックが分散する前提なので、ブロックをまたいだエレメント間でのルールの共有が難しい。そのためプレースホルダー・クラス頼みになるので、見通しがちょっと悪くなる。
body > header nav {
li {
&.current {
border-bottom: 3px double;
}
}
}
&を使ってネストさせるとモディファイアになる。ネストでモディファイアでも良さそうだけど、それだとブロックに対するモディファイアが、エレメントと同じになってしまうので混乱する。Sass (に限らないけど)のネストは深くするべきではないので、2段階のネストをモディファイアと確定させると、これ以上のネストがまず起こらないようになる。
出力されるセレクターに無駄が出るのと、&をSass本来の用途として使っていないところが良くない。
BEMの命名規則を使ったクラス名は役に立つとは思うけど、好きではない。ので、ファイル構成を使ってSassのモジュール化を進めてみた。前にちょっと書いたのを実戦投入し始めたみたいな話。