Stimulusで複数のCSSクラスをオンオフする方法(翻訳)
CSSクラスの動的な追加や削除(切り替え)は、Webアプリでよく行われる操作です。
- 例:
hidden
要素(display: none
)をblock
(display: block
)に変更することで表示する - 例: DOMの下の方にカスケードするクラスを追加する(つまりbody要素に
dark
クラスを追加する)
1個の要素に複数のクラスを追加したい場合があります。私のRails Designerサイトの上部にあるナビゲーションバーがよい例で、下に一定以上スクロールすると、<nav>
要素にbg-white/60
とbackdrop-blur-md
が追加されて、ナビゲーションバーが半透明になります。
これは、Stimulusにあるそれ専用のCSSクラス用APIで実現できます。
最もシンプルな方法は以下のようになります。
<nav data-controller="navigation" data-navigation-scrolling-class="block">
次にこれをnavigation_controller.js
ファイルで以下のように利用します。
export default class extends Controller {
static classes = ["scrolling"];
scroll() {
// IntersectionObserverのスレッショルド/インスタンス化がある程度進むと発動する
this.element.classList.toggle(this.scrollingClass);
}
}
ここではclassList.toggle
という機能を使っています。なるほど見事ですが、CSSクラスが複数の場合はどこに書いたらよいのでしょうか?
DOMのClassList APIのtoggle
に加えて、以下のようにadd
メソッドやremove
メソッドを使うと、以下のようにクラス(の配列)を追加できます。
// ...
scroll() {
this.element.classList.add("bg-white/60", "backdrop-blur-md");
}
// ...
しかし、CSSクラスのリストを以下のようにdata-*
属性の値としてscrolling
に渡そうとしても失敗します。
<nav data-controller="navigation" data-navigation-scrolling-class="bg-white/60 backdrop-blur-md">
どうすれば解決できるでしょうか?
🔗 複数のCSSクラスは複数形のXXXClasses
APIで渡す
Stimulusにはそのための方法がちゃんと用意されています。
CSSクラスを複数渡したいときは、単数形のthis.scrollingClass
ではなく、複数形のthis.scrollingClasses
という名前にすればよいのです。以下のようにこれとJavaScriptのspread構文...
を使えばおしまいです。
// ...
scroll() {
this.element.classList.add(...this.scrollingClasses);
}
// ...
なかなか気の利いた解決法だと思いませんか?
概要
元サイトの許諾を得て翻訳・公開いたします。