CSS Modules の composes: xxx from global; って知ってる?
はじめに
ドワンゴでニコニコ生放送のWebフロントエンジニアをやっています misuken です。
今回は、意外と知られてないかもしれないCSS Modulesの機能 composes: xxx from global;
について紹介します。
from global
とは
公式ドキュメントのComposing from global class namesに書いてある通り、以下のように書いたセレクタをコンポーネントに適用すると、ハッシュなしのクラス名をHTMLへ反映することができます。
.foo {
composes: a b c from global;
}
import classNames from "./foo.module.css";
export const Foo = () => <div className={classNames.foo}></div>;
<div class="foo a b c"></div>
from global
の使いみち
CSS Modulesを使うと、全てのクラスにハッシュが付いてくれるので便利な半面、ハッシュなしのクラスを使えたほうが良い場合もあります。(:global
的な使い方ではなく)
特にスタイルに依存した理由でハッシュなしクラス名を使用したい場合、js側で追加するよりも、CSS側で指定できたほうが、責務を適切に閉じられます。
当然影響範囲が広がればリスクも生じるので、適切な管理のもとに使用しましょう。
from global
は知られているのか?
最初に「意外と知られてないかもしれない」と書いたには理由があります。
個人的にcomposes
でハッシュなしクラス名を指定したい場面は、2016年頃にCSS Modulesを使い始めた頃から存在し、色々な書き方を試してみたものの実現することができず諦めていたからです。
その後も何度もcomposes
でハッシュなしクラス名が指定できたら便利なんだけどなぁ。。。と思ったことがありました。
そんな中、公式ドキュメントを眺めていたところ、なんか見慣れない記述が記載されていました。
公式ドキュメントはやっぱりちゃんと読むべきだなぁ、と思ったのですが。。。
たしか2016年の段階で記述方法に関してはしっかり見た気がするので、改めてリポジトリを見てみました。
すると、2017年10月になにやら更新された様子が見て取れます。
このissue経由でドキュメントに追加されたようです。
どおりで気付かなかったわけですね。
2017年10月以降にCSS Modulesを使い始めた人のほうが認知度が高いかもしれません。
from global
はいつから使えたのか?
ここで新たに一つ疑問が生まれます。
ドキュメントに追加されたのは2017年10月。
しかし、css-loaderなどに含まれる実装側はいつから使えるようになったのか?
それがわかる情報が以下のissueに書いてあります。
どうやら、2015年の段階ですでに使える状態だったようです。
issueのやり取りの中で、何度もドキュメントに追加する流れがあったことが見て取れますが、なぜか記載されることはなく、知る人ぞ知る隠し機能として存在していたと思われます。
2016年に知りたかった。。。
Next.jsのCSS Modules
CSS ModulesをビルトインサポートしているNext.jsでも問題なくfrom global
はサポートされていました。
まとめ
使う場面はそれほど多くないかもしれませんが、使いたくなったときに知ってると知らないでは大きく手間が変わってくるfrom global
は、少し特殊な歴史を辿ってきたことがわかりました。
ニコニコ生放送では、これが使えることで実装を大きく改善できた部分があり、非常に重宝しています。
composes
でハッシュなしセレクタを使いたいなぁと思ったことのある方は、ぜひ試してみてはいかがでしょうか。
Discussion