Tailwind CSSのdata属性で状態スタイルを切り替える方法(data-*)

data-state=openでアコーディオンの開閉スタイルを切り替える例
  • このエントリーをはてなブックマークに追加

スポンサーリンク

タブやアコーディオン、ドロップダウン——「開いているときだけ見た目を変えたい」UIで、JavaScriptからクラスをいちいち付け外ししていませんか? classList.add('active')remove('active') を書いて、状態管理が散らかる……あの面倒くささです。

Tailwind CSSの data属性バリアント(data-*を使うと、JavaScriptは data-state="open" のような属性を切り替えるだけで済み、見た目はTailwind側が宣言的に担当してくれます。この記事では、data-[state=open]: の基本から、v4での真偽値data属性、ヘッドレスUIとの相性、group/peer との併用までを解説します。grouppeer を先に押さえておくと理解が早いので、未読なら peerとは?groupとの違い もどうぞ。

data属性バリアントの基本:data-[state=open]:

HTMLの data-* 属性は、開発者が自由に付けられる「状態の入れ物」です。Tailwindでは data-[属性=値]: の形で、その属性の値に応じてスタイルを当てられます。

<div data-state="open"
     class="h-12 overflow-hidden
            data-[state=open]:h-auto">
  開いているときだけ高さが auto になる
</div>

data-state"open" のときだけ h-auto が効きます。JavaScriptがやることは、この属性を "open""closed" で切り替えるだけ。クラス名を組み立てて付け外しする必要がありません。アコーディオンに使うと、こんな見た目になります。

data-state=openでアコーディオンの開閉スタイルを切り替える例
data-state=”open” のときだけ本文の表示やヘッダーの色を切り替える

真偽値のdata属性は角カッコなしで書ける(v4)

「値はいらない、属性が付いているかどうかだけ見たい」というケースも多いですよね(例:data-active が付いていたら強調)。Tailwind v4では、値を持たない真偽値の data-* 属性は角カッコなしで書けます。

<!-- data-active が付いているときだけ太字+色付き -->
<li data-active class="text-slate-600 data-active:font-bold data-active:text-indigo-600">
  選択中の項目
</li>

値で分岐したいときは data-[state=open]:、属性の有無だけ見たいときは data-active: ——この2つを使い分ければ、たいていの状態表現はカバーできます。

ヘッドレスUIとの相性が抜群

data属性バリアントが真価を発揮するのが、Radix UIやHeadless UIなどの「ヘッドレスUIライブラリ」との組み合わせです。これらのライブラリは、見た目を持たない代わりに、開閉や選択などの状態を data-state="open"data-disabled といった属性で公開してくれます。

つまり、ライブラリが状態を属性で教えてくれる → Tailwindの data-* でその見た目を当てる、という役割分担が自然に成立します。アクセシビリティやキーボード操作はライブラリに任せ、デザインはTailwindで自由に作る。これが今どきのUI実装の定番パターンです。

<!-- Radixなどが data-state を自動で付与してくれる -->
<button class="px-4 py-2 rounded-lg
               data-[state=active]:bg-indigo-500
               data-[state=active]:text-white">
  タブ
</button>

group / peer と組み合わせる

data属性は、grouppeer とも組み合わせられます。親の状態で子を変えたいなら group-data-[...]:兄弟の状態で変えたいなら peer-data-[...]: です。

<!-- 親が data-state="open" のとき、中の矢印アイコンを回転 -->
<div data-state="open" class="group">
  <svg class="transition group-data-[state=open]:rotate-180">...</svg>
</div>

「アコーディオンを開いたら矢印が 180度 回る」のような演出が、JavaScriptでクラスを足さずに書けます。group の親→子、peer の兄弟→兄弟という関係に data-* を乗せるイメージです。この関係の基礎は peerとは?groupとの違いgroupを入れ子にする方法 で解説しています。

まとめ

Tailwindのdata属性バリアントを振り返ります。

  • 値ありは data-[state=open]:、真偽値は data-active:(v4は角カッコ不要)
  • JavaScriptは属性を切り替えるだけ、見た目はTailwindが宣言的に担当
  • Radix・Headless UIなどヘッドレスUIと組み合わせると役割分担がきれいに決まる
  • 親の状態は group-data-[...]:、兄弟の状態は peer-data-[...]:

タブやアコーディオンを作る機会があれば、まず data-[state=open]: を試してみてください。状態管理がぐっとシンプルになります。関連して、peerとgroupの違い、全体像は Tailwind CSSの使い方【初心者向け】 もどうぞ。

スポンサーリンク

  • このエントリーをはてなブックマークに追加