タブUIは、限られたスペースで多くの情報を整理し、ユーザーに提供するのに便利なデザインパターンです。
しかし、従来のタブUIの実装には、JavaScriptによる複雑な処理が必要でした。
htmxを使えば、シンプルなHTMLの属性だけで動的なタブUIを実現できます。
この記事では、htmxを使ってタブUIを実装する方法を詳しく解説します。
本記事の内容
- タブUIのHTML構造
- タブコンテンツの動的生成
- アニメーション効果の追加
- アクセシビリティの考慮
- サンプルコード
- まとめ
それでは、上記に沿って解説していきます。
タブUIのHTML構造
htmxについてよくわからない場合は、次の記事からご覧ください。
まず、タブUIのHTML構造を定義します。
タブボタンとタブコンテンツを以下のように配置します。
<div class="tab-container" role="tablist"> <div class="tab-buttons"> <button class="tab-button" role="tab" aria-controls="tab-content" aria-selected="true" hx-target="#tab-content" hx-trigger="click" hx-get="tab1.php">タブ1</button> <button class="tab-button" role="tab" aria-controls="tab-content" hx-target="#tab-content" hx-trigger="click" hx-get="tab2.php">タブ2</button> <button class="tab-button" role="tab" aria-controls="tab-content" hx-target="#tab-content" hx-trigger="click" hx-get="tab3.php">タブ3</button> </div> <div id="tab-content" role="tabpanel"></div> </div>
各タブボタンには、hx-target、hx-trigger、hx-getの属性を設定します。
これにより、ボタンのクリックイベントが発火した際に、指定したPHPファイルからコンテンツを取得し、#tab-content要素に挿入するようになります。
タブコンテンツの動的生成
次に、PHPを使ってタブコンテンツを動的に生成します。
tab1.php、tab2.php、tab3.phpというPHPファイルを作成し、以下のようなコードを記述します。
<!-- tab1.php --> <?php $title = 'タブ1のコンテンツ'; $content = 'これはタブ1の動的に生成されたコンテンツです。'; ?> <div> <h2><?= $title ?></h2> <p><?= $content ?></p> <p>現在の時刻は <?= date('Y-m-d H:i:s') ?> です。</p> </div>
<!-- tab2.php --> <?php $title = 'タブ2のコンテンツ'; $content = 'これはタブ2の動的に生成されたコンテンツです。'; ?> <div> <h2><?= $title ?></h2> <p><?= $content ?></p> <p>現在の時刻は <?= date('Y-m-d H:i:s') ?> です。</p> </div>
<!-- tab3.php --> <?php $title = 'タブ3のコンテンツ'; $content = 'これはタブ3の動的に生成されたコンテンツです。'; ?> <div> <h2><?= $title ?></h2> <p><?= $content ?></p> <p>現在の時刻は <?= date('Y-m-d H:i:s') ?> です。</p> </div>
これらのPHPファイルでは、$titleと$contentという変数を使ってタブコンテンツを動的に生成しています。
また、date(‘Y-m-d H:i:s’)を使って現在の時刻を表示することで、ページが動的に生成されていることを強調しています。
htmxは、これらのPHPファイルをAjaxで取得し、#tab-content要素に挿入します。
これにより、タブを切り替えるたびに、対応するコンテンツが動的に表示されます。
アニメーション効果の追加
タブ切り替えのアニメーションを追加することで、よりスムーズで洗練された印象を与えることができます。
以下のようなCSSを使って、アニメーションを実装します。
.tab-content { opacity: 0; transition: opacity 0.5s; } .tab-content.htmx-settling { opacity: 1; }
htmx-settlingクラスは、htmxがコンテンツの挿入を完了した直後に要素に追加されます。
これを利用して、コンテンツの表示をフェードインさせます。
アクセシビリティの考慮
タブUIをアクセシブルにするために、WAI-ARIAの属性を使います。
<div class="tab-container" role="tablist"> <div class="tab-buttons"> <button class="tab-button" role="tab" aria-controls="tab-content" aria-selected="true" hx-target="#tab-content" hx-trigger="click" hx-get="tab1.php">タブ1</button> <button class="tab-button" role="tab" aria-controls="tab-content" hx-target="#tab-content" hx-trigger="click" hx-get="tab2.php">タブ2</button> <button class="tab-button" role="tab" aria-controls="tab-content" hx-target="#tab-content" hx-trigger="click" hx-get="tab3.php">タブ3</button> </div> <div id="tab-content" role="tabpanel"></div> </div>
role属性を使って、タブボタンとタブコンテンツの役割を明示します。
また、aria-controls属性でタブボタンとタブコンテンツの関連付けを行います。
aria-selected属性で、現在選択されているタブを示します。
さらに、キーボードでのタブ操作を可能にするために、JavaScriptを使って以下のような処理を追加します。
const tabButtons = document.querySelectorAll('.tab-button'); tabButtons.forEach((button, index) => { button.addEventListener('keydown', (event) => { if (event.key === 'ArrowLeft') { tabButtons[(index - 1 + tabButtons.length) % tabButtons.length].focus(); } if (event.key === 'ArrowRight') { tabButtons[(index + 1) % tabButtons.length].focus(); } }); });
これで、左右の矢印キーを使ってタブを切り替えられるようになります。
サンプルコード
以上の内容を組み合わせた完全なサンプルコードは以下の通りです。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>htmxで作る動的タブUI</title> <script src="https://unpkg.com/htmx.org@1.7.0"></script> <style> .tab-content { opacity: 0; transition: opacity 0.5s; } .tab-content.htmx-settling { opacity: 1; } </style> </head> <body> <div class="tab-container" role="tablist"> <div class="tab-buttons"> <button class="tab-button" role="tab" aria-controls="tab-content" aria-selected="true" hx-target="#tab-content" hx-trigger="click" hx-get="tab1.php">タブ1</button> <button class="tab-button" role="tab" aria-controls="tab-content" hx-target="#tab-content" hx-trigger="click" hx-get="tab2.php">タブ2</button> <button class="tab-button" role="tab" aria-controls="tab-content" hx-target="#tab-content" hx-trigger="click" hx-get="tab3.php">タブ3</button> </div> <div id="tab-content" role="tabpanel"></div> </div> <script> const tabButtons = document.querySelectorAll('.tab-button'); tabButtons.forEach((button, index) => { button.addEventListener('keydown', (event) => { if (event.key === 'ArrowLeft') { tabButtons[(index - 1 + tabButtons.length) % tabButtons.length].focus(); } if (event.key === 'ArrowRight') { tabButtons[(index + 1) % tabButtons.length].focus(); } }); }); </script> </body> </html>
このコードを実行すると、シンプルで高速な動的タブUIが実現されます。
まとめ
この記事では、htmxとPHPを組み合わせて動的なタブUIを実装する方法を解説しました。
htmxのhx-target、hx-trigger、hx-get属性を使うことで、シンプルなHTMLだけで動的なタブ切り替えを実現できます。
また、PHPを使ってタブコンテンツを動的に生成することで、より柔軟で応用の効くUIが作成できます。
htmxとサーバーサイドの処理を連携させることで、高速で洗練されたタブUIを実装できます。
この記事で紹介したテクニックを活用し、さらに発展させることで、ユーザーにとって使いやすく魅力的なタブUIを作成しましょう。