Bootstrap5.x にはUtilityAPIという仕組みがあるのですが、これを活用して生成されるクラスに手を入れようとしたらうまくいかずにハマりました。
やろうとしたこと
Sizingカテゴリに属する width/height をGridよろしくレスポンシブに出来ないかな~と思い、手を付けたのが発端でした。
コードは後述しますが、意図通りに動作すれば元々あるw-25
やw-50
、w-auto
といったクラスの他に、w-sm-25
、w-md-25
、w-lg-25
のような規則のクラスが誕生するはずでした…が、うまくいかず。
失敗例
デフォルトの定義をそのまま流用しつつ、一部分を改変できるサンプルがあったので、これを参考に scss を書いてみます。
// このファイルはReactを使ったフロントアプリの一部からimportされていますが、
// この記事とは関係ない部分なので省きます
@import "bootstrap/scss/bootstrap";
@import "scss/utilities";
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
// ↓のimportも必要(utilitiesが依存してるので)
@import "bootstrap/scss/maps";
@import "bootstrap/scss/utilities";
$utilities: map-merge(
$utilities,
(
"width": map-merge(
map-get($utilities, "width"),
(responsive: true)
)
)
);
生成された css を見てもw-sm-25
みたいなのは見当たらず。
成功例
App.scss
に記載していた import の順番を逆にした所、意図通りにクラスが生成されました。
bootstrap 本体の import よりも先に $utilities に対しての変更を行う必要があったようです。
// このファイルはReactを使ったフロントアプリからimportされていますが、
// 記事とは関係ない部分なので省きます
+ @import "scss/utilities";
@import "bootstrap/scss/bootstrap";
- @import "scss/utilities";
なんでや
今回の例では下記のような形で bootstrap 本体を import しています。
じつは、この中にヒントがありました。
@import "bootstrap/scss/bootstrap";
上記のソースを見てみると、ファイルの末尾で "utilities/api" を import しています。
この "utilities/api" は、bootstrap にて定義された $utilities 等の変数から実際に CSS クラスを生成する役割を持っているようです。
生成処理が実行されるタイミングは"utilities/api"が import されたタイミング(≒bootstrap 本体が import されたタイミング)なので、これよりも後に加えられた変更は生成された CSS クラス群には反映されないようです。
改めて失敗例を見てみると、 "utilities/api" の import よりも後に変更を行っており、まさしく前述の通りのパターンになっていました。変更が反映されなかったのも当然の帰結…
所感
bootstrapなんもわからん。
あと、元々あったクラスと生成されたクラスの中身に差がなくて泣いた