このウェブサイトの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のモジュール化を進めてみた。前にちょっと書いたのを実戦投入し始めたみたいな話。