この記事が解説すること
tailwindcss だけでモーダルを実装する方法を解説します。
本気で tailwindcss だけしか使えない環境はレアだと思いますが、でも tailwindcss だけで済むのだったらそれが何よりという環境の方はいると思って書いていきます。
結論のコードはこれ
<a href="#modal" class="block w-fit"><img src="/dist/sample_thumb.jpg" class="w-24 rounded-lg" /></a>
<div id="modal" class="hidden target:block">
<div class="block w-full h-full bg-black/70 absolute top-0 left-0">
<a href="#" class="block w-full h-full cursor-default"></a>
<div class="w-3/4 mx-auto mt-20 relative -top-full">
<img src="/dist/sample.jpg" />
</div>
</div>
</div>
もしくはこれ。
<div class="group">
<button class="block w-fit"><img src="/dist/sample_thumb.jpg" class="w-24 rounded-lg" /></button>
<div class="hidden group-focus-within:block">
<div class="block w-full h-full bg-black/70 absolute top-0 left-0">
<button class="block w-3/4 mx-auto mt-20">
<img src="/dist/sample.jpg" />
</button>
</div>
</div>
</div>
見た目はこうなる
before | after |
---|---|
use_fragment_modal.html の解説
1行目と2行目がほぼ本質となります。
1行目の<a href="#modal">
と2行目の <div id="modal" class="hidden target:block">
で、リンクをクリックしたときに2行目以降の div の中身が表示されるようになります。
https://tailwindcss.com/docs/hover-focus-and-other-states#target
上記のマニュアルにある通り、 target:
は要素の ID が現在の URL フラグメントと一致するときにスタイルを適用するように指示する擬似クラスです。
1行目のリンク先は #modal
で、これは2行目の id="modal"
に一致するので、デフォルトでは hidden
であったスタイルがこの時に block
へと変わり、2行目以降に記述されている要素が見えるようになります。
あとは2行目の div の中身がモーダルっぽい挙動をするように調整すればいいだけです。
今回は4行目のa要素を画像の下に敷く感じで、画像以外のところをクリックしたらモーダルが閉じるようにしてみました。
no_fragment_modal.html の解説
1行目と3行目、そして button
要素がキモです。
1行目で class="group"
を指定していますが、この group
クラスの子要素で group-{modifire}
を指定すると、 group
クラスの状態が拾えるようになります。3行目の group-focus-within:block
がそれです。
https://tailwindcss.com/docs/hover-focus-and-other-states#styling-based-on-parent-state
そして、その3行目の group-focus-within
がどのような状態を拾うのかですが、まず focus-within
が何なのかを見てみます。
https://tailwindcss.com/docs/hover-focus-and-other-states#focus-within
ここには、このクラスを指定した要素か、その子要素にフォーカスがあるときにスタイルを適用できるようになると解説されています。
それが group-focus-within
になると、 group
を指定した要素か、その子要素にフォーカスがあるときにスタイルが適用できるようになるのです。
今回2つの button
がありますが、 どちらの button
も <div class="group">
の子要素なので、どちらをクリックしても group-focus-within:block
が適用されます。
イメージとしては、サムネイルにかかっている button
はモーダルを開くためのボタンですが、モーダル上の画像にかかっている button
はモーダルを開き直しているボタンとなります。
もし画像にかかっている button
を div
に変更したら、画像をクリックしたときにもモーダルが閉じてしまうようになります。それを防ぐために、画像を button
要素の下に持ってきて、画像をクリックしたときにも再度モーダルを開くことで、擬似的に画像をクリックしても閉じないモーダルに見せかけているのです。
まとめ
ちょっと夜中のテンションで書き殴ったものなので、解説が分かりにくいかも知れません。
ただ、意外と tailwindcss だけでモーダルを作った記事というのが見当たらなかったのでこの記事を書きました。 tailwindcss 周りは便利なツールがたくさんあり、それらを使ったモーダルの作り方はあるのですが…。けれども、そうしたツールを導入できなかったり、依存先を増やしたくないという判断だったりで、tailwindcss だけで物事が済んでくれたらと思うことはそれなりにあるのかなぁと思います。
そんな環境にいる方の参考になれば幸いです。