[記事の内容]

通常のタブUIは1階層のみですが、タブの中にさらにタブを設置することで、情報を整理しやすくなります。
完成形のイメージを確認します。
デモサイトはコチラから。
親タブをクリックすると、その中に子タブが表示される構造です。
まずはベースとなるHTML構造を作成します。親タブと子タブを分けて記述することがポイントです。
基本構造の書き方は以下のようになります。
<div class="contents">
<div class="tab">
<ul class="top-btn">
<li class="tab-btn active" data-tab="tab1">タブ1</li>
<li class="tab-btn" data-tab="tab2">タブ2</li>
</ul>
</div>
<!--tab 上のボタンを用意-->
<div id="tab1" class="tab-content active">
<p>タブ1の内容です</p>
<!-- 子タブ -->
<ul class="sub-tab">
<li class="sub-tab-btn active" data-sub="sub1">サブ1</li>
<li class="sub-tab-btn" data-sub="sub2">サブ2</li>
</ul>
<!-- コンテンツ(↑ボタンの下に配置) -->
<div class="sub-contents">
<div id="sub1" class="sub-content active">サブ1の内容</div>
<div id="sub2" class="sub-content">サブ2の内容</div>
</div>
</div>
<!--tab1の全体を囲む(コンテンツ)-->
<div id="tab2" class="tab-content">
<p>タブ2の内容です</p>
<!-- 子タブ -->
<ul class="sub-tab">
<li class="sub-tab-btn active" data-sub="sub3">サブ2-1</li>
<li class="sub-tab-btn" data-sub="sub4">サブ2-2</li>
</ul>
<!-- コンテンツ(ボタンの下に配置) -->
<div class="sub-contents">
<div id="sub3" class="sub-content active">サブ3の内容</div>
<div id="sub4" class="sub-content">サブ4の内容</div>
</div>
</div>
<!--tab2の全体を囲む(コンテンツ)-->
</div>
top-btnを用意します。data-tab="tab1"、data-tab="tab2"と、ボタンが増える度に、data-tabの中身を数字を変更してください。activeを忘れずに、記述しておいてください。id="tab1" class="tab-content active"〜/divactiveを忘れずに、記述しておいてください。data-sub="sub○"、コンテンツのid="sub○"は、合わせておくようにしておいてください。id="tab2" class="tab-content"〜/divid="tab2"と指定してください。id="tab3"と指定してください。見た目を整えるためにCSSを設定します。activeクラスの切り替えが重要です。
書き方は以下のようになります。
/* 全体 */
.contents {
max-width: 960px;
width: 94%;
margin: 5rem auto;
}
/* =========================
親タブ(上)
========================= */
.top-btn {
display: flex;
padding: 0;
margin: 0;
list-style: none;
border-bottom: 2px solid #ccc;
}
.tab-btn {
font-size: 18px;
font-weight: bold;
flex: 1;
text-align: center;
padding: 20px;
cursor: pointer;
background: #eee;
border: 1px solid #ccc;
border-bottom: none;
transition: 0.2s;
}
.tab-btn + .tab-btn {
border-left: none;
}
/* アクティブ */
.tab-btn.active {
background: #395848;
color: #fff;
font-weight: bold;
}
/* =========================
タブコンテンツ
========================= */
.tab-content {
display: none;
border: 1px solid #ccc;
padding: 20px;
}
.tab-content.active {
display: block;
}
/* =========================
子タブ(中)
========================= */
.sub-tab {
display: flex;
padding: 0;
margin: 20px 0 0;
list-style: none;
border-bottom: 2px solid #ccc;
}
.sub-tab-btn {
font-size: 16px;
font-weight: bold;
flex: 1;
text-align: center;
padding: 14px;
cursor: pointer;
background: #f5f5f5;
border: 1px solid #ccc;
border-bottom: none;
transition: 0.2s;
}
.sub-tab-btn + .sub-tab-btn {
border-left: none;
}
.sub-tab-btn.active {
background: #395848;
color: #fff;
}
/* =========================
子コンテンツ(下)
========================= */
.sub-contents {
border: 1px solid #ccc;
padding: 15px;
}
.sub-content {
display: none;
}
.sub-content.active {
display: block;
}
.tab-btn.activeで、active時にCSSを適用させます。.tab-content、.sub-contentには、display: noneを指定しておきます。JavaScriptでクリック時の切り替え処理を実装します。親タブと子タブをそれぞれ制御します。
書き方は以下のようになります。
// 親タブ
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.addEventListener('click', () => {
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
btn.classList.add('active');
document.getElementById(btn.dataset.tab).classList.add('active');
});
});
// 子タブ
document.querySelectorAll('.sub-tab-btn').forEach(btn => {
btn.addEventListener('click', () => {
const parent = btn.closest('.tab-content');
parent.querySelectorAll('.sub-tab-btn').forEach(b => b.classList.remove('active'));
parent.querySelectorAll('.sub-content').forEach(c => c.classList.remove('active'));
btn.classList.add('active');
parent.querySelector('#' + btn.dataset.sub).classList.add('active');
});
});.tab-btnと.sub-tab-btnをすべて取得して、クリックイベントを設定します。activeを削除、すべてのコンテンツも非表示にします。activeを付けます。data-tabやdata-subの値を使って、一致するIDのコンテンツを表示します。closest('.tab-content')を使って、親タブの中だけで子タブを切り替えます。今回はこれで以上です。
今回はJavaScriptを使って、タブの中にタブを設置する方法を解説しました。
少し複雑ですが、仕組みを理解すれば応用も可能です。
2026.04.05
2026.03.29
2026.03.14
2026.03.08
2026.03.01
2026.02.26
2023.06.15
2022.06.30
2020.03.22
2020.03.06

© 2025 shu-naka-blog