超モダンなCSS設計を考える。ごめん、タイトル負けした。

こんにちは、榊原です。
先ほど、TAMさんの「CSSの設計 – FLOCSSをベースにしたファイルの構成と命名規則を考える」をみて、堅実な設計と命名規則に「なるほど」と頷く部分、ちょっと私と違うなぁと思う部分があったりととても楽しかったです。
 
そこで思い浮かぶ「じゃあ、超モダンなCSS設計ってどんなのだろう」という疑問。
以下、しっかりと理論化して「こっちの方がいい」といえる内容でなくて恐縮なのですが、Twitterなどで「いやいや、馬鹿いってるんじゃねーよ」とかわいわいしていただけると嬉しいです。

BEMとかやめて、モジュール毎に親子関係で縛ってしまおう

CSS設計で、最初に行うべきは「パーツを使い回し可能なモジュールとみなして」設計することです。
CSSフレームワーク「Bootstrap」を一度つかってみるとわかりますが、CSSフレームワークとは「使い回し可能なモジュール群」です。このようなものをできるだけ増やすのが従来のCSS設計でした。

その中で生まれ、今でも多くの人に親しまれ続けているのが「BEM」という設計です。モジュールをBlock-Element-Modifyの単位にして、その親子関係がわかる命名規則を使うやり方です。
 

.block
.block__element
.block__element--modifier
.block--modifier
.block--modifier__element

 
という表現方法で、例えばこれでモジュールを表現してみると以下のような感じ。
 

<div class="block">
    <div class="block__element"></div>
    <div class="block__element--modifier"></div>
</div>
<div class="block--modifier">
    <div class="block--modifier__element"></div>
</div>

 
CSSは思想的に、block__elementだけ抜き取っても使える設計であるべきで、でもその反面、CSS設計者は「予期しない使われ方なんてしてほしくない」と考えるので、見事に双方に妥協した形といえるでしょう。
 

.block .block--modifier .block--modifier__element .utility1 .utility2 {
}

 
とか、どんどん入れ子を増やしていったら、CSS読みにくいじゃねーか!という実務的な面も。
 
しかし、私達はSassを手に入れました。後述しますが、CSSをグローバル空間で適応しないようにJSを使ってCSSをロードする技術もでてきています。もう、CSSの思想に媚びなくても、もっと自由に振る舞っても許されるようになった、のかもしれません!
 
もうモジュール単位で
 

.block {
    .block--modifier {
        .block--modifier__element {
        }
    }
}

 
でいいのです。だって、CSS設計者、使い回してほしくないんでしょ?だったら親子関係をしっかりしましょうよ。
そしたら、命名規則ももっと自由に

.block {
    ul {
        li {
        }
    }
}

とかで大丈夫。下層ページ一箇所でしか使わなかった、position:relative;left:1px; みたいなutility用CSSをグローバルに配置して、間違っても重複しないように、.utility-hoge-01 みたいにナンバリングする必要もない!
 
ちなみに、「いやいや、ulだけ抜き取って使いまわしたいし!」とかいう方もおられると思いますが、その方はモジュールの設計単位が間違ってるだけ。ulだけでモジュール化して下さい。ちなみに、これを .page1 とかでページ毎でくくる方は、CSSの基礎から勉強し直してきて下さい。
 
ま、まだここらへんまでなら石は投げられないはず。大丈夫、大丈夫ですよね??
 

再利用しないものはモジュール化しない

モジュール化を前提としたために、再利用しないものまで「いつかの将来のために」モジュール化していませんか??
 
例えばトップページでしか使わないHERO画像。キャッチコピー用モジュール。
小さなところでいうと、先ほどのutility用CSS。どこでどれを使ったか把握しきれていますか??わからないまま、ナンバリングを重ねるとか・・・。
 
そう! CSS Modulesなら、もうこんなことする必要はありません。

CSSモジュールは、CSSの適応範囲をグローバルではなく、コンポーネント単位で分割するための技術です。Angular2とかReact.jsで使えます。これを使えば、例えば、

.title{
    font-size:1rem;
}

と書いたものが、CSSモジュールによって勝手に

.title[_ngcontent-hpw-5] {
    font-size:1rem;
}

みたいに変換。ついでにテンプレート側のHTMLも自動的に_ngcontent-hpw-5=””って挿入されるから、汚染とか気にしないでいいよ!(詳細を知りたい方は「CSSモジュール ― 明るい未来へようこそ」をご参照ください)
 
え、普通の静的サイトでは使えない?
「超モダン」ってタイトルだからご容赦ください。普通の静的サイトだったら、ぶっちゃけHeaderに直書きするぐらいでいいんじゃないかな(投げやり)
 

まとめ

 
タイトルを仰々しくしたけど、あまり思いつかなかったです、ごめんなさい。

お問い合わせ