タブの入れ子に対応(ネストタブ)
タブの中にさらにタブを持てる「ネストタブ」の実装例です。 外側タブで大きなカテゴリを切り替え、その中にある内側タブで詳細を切り替えることができます。 複数階層を整理して見せたいUIに便利で、ARIA対応済み・コピペですぐ利用できます。
- 外側タブと内側タブの二重構造に対応
- カテゴリと詳細の切替に最適
- ARIA属性でアクセシブルな設計
- シンプルなJSで複数階層の切替を管理
コードについて
本記事のコードは AI(ChatGPT)による生成をベースに作成・調整しています。ご利用の環境でテストの上ご使用ください。
免責 本コードの利用に伴う不具合・損害について、当サイトは責任を負いません。自己責任にてご利用ください。
免責 本コードの利用に伴う不具合・損害について、当サイトは責任を負いません。自己責任にてご利用ください。
デモ
カテゴリAの内容
詳細A-1 のコンテンツです。
コードをコピーして使おう!
/* =========================
ネスト対応タブUIのCSS(全文コメント)
-----------------------------------------
・このスタイルは #nested-tabs 配下に限定して適用します
・外側タブと内側(入れ子)タブは同じクラス名(.tabs / .tab / .tabpanel)
を使い、スコープで衝突を回避します
・ARIA属性(aria-selected / aria-hidden)と連動して視覚状態を切替えます
========================= */
/* ===== 全体スコープ(フォント/色/幅) ===== */
#nested-tabs{
font-family: system-ui,-apple-system,"Segoe UI",Roboto,"Noto Sans JP",sans-serif; /* 可読性が高い汎用フォントスタック */
color:#0f172a; /* 基本文字色(濃いネイビー系) */
max-width: 720px; /* セクションの最大横幅(レイアウトが横に伸びすぎないよう制限) */
margin:0 auto; /* 画面中央に配置(左右オートマージン) */
padding:0 16px; /* 画面端で文字がつかないよう左右に余白を確保(任意) */
box-sizing:border-box;/* パディング込みで幅計算(安全策) */
}
/* ===== タブリスト(外側/内側とも共通) ===== */
#nested-tabs .tabs{
display:flex; /* 子要素(.tab)を横並びにする */
gap:6px; /* タブ同士の間隔を6px空ける */
margin:12px 0; /* タブリストの上下に余白を設ける */
flex-wrap:wrap; /* 画面が狭いときは折り返してレイアウト崩れを防止 */
}
/* ===== タブボタン(外側/内側とも共通) ===== */
#nested-tabs .tab{
appearance:none; /* ブラウザ既定のボタン装飾を解除(クロスブラウザ安定) */
padding:6px 12px; /* クリックしやすい内側余白 */
border:1px solid #e5e7eb; /* 薄いグレーの枠線 */
border-radius:8px; /* 角丸で柔らかい見た目に */
background:#fff; /* 背景は白 */
color:inherit; /* 文字色は親の color を継承 */
cursor:pointer; /* ホバー時にポインターを表示 */
line-height:1.2; /* テキストの行高を少しゆったりに */
white-space:nowrap; /* ラベルの折返しを防止(必要に応じて解除) */
transition:
background-color .2s ease,
border-color .2s ease,
color .2s ease,
transform .05s ease; /* 状態変化を滑らかに */
}
/* アクティブ感のある押下フィードバック(任意) */
#nested-tabs .tab:active{
transform: translateY(1px); /* クリック中に1px沈む演出 */
}
/* フォーカス可視化(キーボード操作のアクセシビリティ向上) */
#nested-tabs .tab:focus-visible{
outline:2px solid #0b6bff; /* アクセント色でアウトライン表示 */
outline-offset:2px; /* ボタンから少し離して見やすく */
}
/* ===== 選択状態のタブ(aria-selected="true") =====
JS 側で選択タブに aria-selected="true" を付与する前提。
視覚的にも「選ばれている」ことが分かるよう配色を変更。 */
#nested-tabs .tab[aria-selected="true"]{
background:#0b6bff; /* アクティブ背景をアクセント色に */
color:#fff; /* 文字は白でコントラスト確保 */
border-color:#0b6bff; /* 枠線もアクセント色に揃える */
font-weight:600; /* やや強調 */
}
/* ===== パネル(表示領域)の既定状態 =====
すべてのパネルを非表示にしておき、表示すべきパネルだけ
aria-hidden="false" を付与して見せる運用。 */
#nested-tabs .tabpanel{
display:none; /* 既定は非表示 */
}
/* ===== パネル(表示中:aria-hidden="false") =====
JS 側で対応パネルに aria-hidden="false" を付け替える。 */
#nested-tabs .tabpanel[aria-hidden="false"]{
display:block; /* 表示に切替 */
border:1px solid #e5e7eb; /* コンテンツ領域を囲う薄い枠線 */
border-radius:8px; /* 角丸 */
padding:12px; /* 内側余白 */
margin-bottom:12px; /* 下に余白(次のブロックと干渉しないように) */
background:#fff; /* 背景を白で読みやすく */
box-sizing:border-box; /* 枠線/パディング込みの幅計算 */
}
/* ===== 補助クラス(任意) ===== */
#nested-tabs .panel-outer{ /* 外側パネルの差別化用(必要なら有効化) */ }
#nested-tabs .panel-inner{ /* 内側パネルの差別化用(必要なら有効化) */ }
コメント