こんにちは。エキサイトでデザイナーをしている齋藤です。
今回は、htmxのhx-indicator
とTailwind CSSを組み合わせてスケルトンスクリーンを実現する方法をご紹介します。
スケルトンスクリーンとは
スケルトンスクリーンは、読み込み中にコンテンツの代替となる図形を表示して、処理が実行中であることなどをユーザーに示すUXテクニックの一つです。
Tailwind CSSでスケルトンスクリーンをスタイリングする
Tailwind CSSでは、スケルトンスクリーン用のアニメーションが標準搭載されており、簡単にスタイリングできます。
スタイリングについては、以下の記事で詳しく説明しておりますので本稿では割愛します。
htmxでリクエスト中のみ特定の要素を可視化するhx-indicator
htmxでは、リクエスト中のみ特定の要素を可視化する機能として、hx-indicator
属性が用意されています。
hx-indicatorの基本
hx-get
などのAJAXリクエストをする属性が付与された要素に、hx-indicator
属性を追加して値にはリクエスト中に可視化したい要素のidかclassを指定します。
また、可視化したい要素のclassにhtmx-indicator
を指定します。
<div> <button type="button" hx-get="..." hx-indicator="#loading">Request</button> <!-- リクエスト中は以下の要素が表示される --> <div id="loading" class="htmx-indicator">...</div> </div>
仕組みは単純です。
hx-indicator
を使用すると、htmxによって自動的に以下のスタイルがhtmlに挿入されます。
<style> .htmx-indicator{ opacity:0; transition: opacity 500ms ease-in; } .htmx-request .htmx-indicator{ opacity:1; } .htmx-request.htmx-indicator{ opacity:1; } </style>
処理の流れは次の通りです。
htmx-indicator
はopacity:0;
(不透明度0%)が指定されている- リクエスト中にはclassに
htmx-request
が加えられる htmx-request
と同居する場合はhtmx-indicator
がopacity:1;
(不透明度100%)になり要素が可視化される
Tailwind CSSと組み合わせる
リクエスト中にTailwind CSSでスタイリングしたスケルトンスクリーンを表示させたいとします。
See the Pen Untitled by AyumuSaito (@ayumusaito-excite) on CodePen.
<button type="button" hx-get="..." hx-indicator="#loading">Request</button> <!-- リクエスト中は以下の要素を表示させたい --> <div id="loading" class="htmx-indicator"> <div class="p-4 rounded bg-white border border-slate-300"> <div class="animate-pulse flex gap-3"> <div class="w-12 h-12 aspect-square rounded-full bg-slate-300"></div> <div class="flex flex-col gap-2"> <div class="h-6 w-24 rounded bg-slate-300"></div> <div class="h-6 w-40 rounded bg-slate-300"></div> <div class="h-6 w-80 rounded bg-slate-300"></div> </div> </div> </div> </div>
注意点
この時に注意が必要です。
というのも、標準のhx-indicator
のスタイルはopacity
を使用して要素の可視化を行うため、スケルトンスクリーン用の要素のスペースが常に確保されてしまいます。
そのため、hx-indicator
用のスタイルを独自定義する必要があります。
スペースの確保を回避するためには、opacity
ではなくdisplay
を用いて制御するようにします。
独自定義するスタイルのclass名はhtmx-indicator
以外を使用します。
<style> .my-indicator{ display:none; } .htmx-request .my-indicator{ display:block; } .htmx-request.my-indicator{ display:block; } </style>
完成形
先に述べた独自定義のスタイルを使用した完成形は以下の通りです。
<head> ... <!-- displayを使用するように独自定義したhx-indicator用のスタイル --> <style> .my-indicator{ display:none; } .htmx-request .my-indicator{ display:block; } .htmx-request.my-indicator{ display:block; } </style> </head> <body> <button type="button" hx-get="..." hx-indicator="#loading">Request</button> <!-- リクエスト中は以下の要素が表示される --> <div id="loading" class="my-indicator"> <div class="p-4 rounded bg-white border border-slate-300"> <div class="animate-pulse flex gap-3"> <div class="w-12 h-12 aspect-square rounded-full bg-slate-300"></div> <div class="flex flex-col gap-2"> <div class="h-6 w-24 rounded bg-slate-300"></div> <div class="h-6 w-40 rounded bg-slate-300"></div> <div class="h-6 w-80 rounded bg-slate-300"></div> </div> </div> </div> </div> </body>
さいごに
今回は、htmxのhx-indicator
とTailwind CSSを組み合わせてスケルトンスクリーンを実現する方法をご紹介しました。
実装が手間なスケルトンスクリーンですが、htmxを使用することにより、JSを書かずにマークアップと同じ感覚で実現できます。
htmx、Tailwind CSSを使用される方の一助となれば幸いです。
ご精読ありがとうございました。