honey-css-modules/ADR/:localと:globalをサポートしない
公開日: 2024/11/19
ステータス
Accepted (2024/11/19)
背景
CSS Modules の仕様では、:local(...)/:global(...)とは別に、:local/:globalという引数なしの構文が規定されてる
しかしこの構文の仕様が複雑
実装もかなり面倒
加えて挙動が直感的でなくて誤った使われ方をされてしまうケースがあったり、奇妙な挙動がある
殆どの場合、:local/:globalは:local(...)/:global(...)で置き換えられるはず
そのため、:local/:globalをサポートしたい強い理由もない
よって、:local/:globalをサポートしないことにしたい
決定事項
:local/:globalをサポートしない
:local/:globalが使われていたらエラーを出す
参考
:local/:globalの挙動
selector node の中で使える構文であり、:localが書かれた以降のクラスセレクターを local scope 化する。:globalの場合は、:localが書かれた以降のクラスセレクターを global scope 化する。
code:a.module.css
.a :global .b .c :local .d .e {} /* a, d, e が local scope、b, c が global scope */
効力は同じ selector node の中だけで、他の selector node には影響しない
code:a.module.css
:is(:global .a .b) .c {} /* c が local scope、a, b が global scope */
postcss-modules の実装では、複数のセレクターのリストで利用されている場合、それぞれのセレクターで異なる scope にするとエラーになる
code:a.module.css
/**
* 1つ目のセレクターが global scope、2つ目のセレクターが local scope なのでエラー。
*
* NOTE: 2つ目のセレクターが global scope にならないのは、:global の効力が
* 同じ selector node の中だけだから。
*/
:global .a, .b {}
/* 1つ目のセレクターが local scope、2つ目のセレクターが global scope なのでエラー */
.a, :global .b {}
/**
* 1つ目のセレクターの先頭は local scope だが、末尾は global scope であり、
* 2つ目の scope と一致している。postcss-modules の実装では、1つ目のセレクターの末尾の
* scope と、他のセレクターの scope が一致しているかを判定している。よってエラーにならない。
*/
.a :global .b, :global .c {}
:local/:globalのよくある誤った使われ方
1. 全てを global scope 化しようとして:global .a .b, .c .d { ... } と書く
a, b, c, d 全てを global scope 化することを意図したコード
2. ブロック全体をグローバル化しようとして:global {...}と書く
例えば以下のようにして、a, b 全てを global scope にするつもりで書いたりとか
code:a.module.css
:global {
.a {}
.b {}
}
:globalの効力はその selector node の中だけなので、a も b も local scope になってしまう
mizdra.icon まあこれをよくある誤った使われ方として挙げるのは言いがかりっぽいが...
そもそも postcss-modules の実装が奇妙
しかし実際にはエラーにはならず、a, b が global scope として出力される
テストケースもちゃんと用意されているので、期待通りの挙動ではありそうだが...非常に奇妙
あと前の selector の scope を次の selector が引き継いでいるのもおかしいと思う
b は local scope になるべきでは?