素のCSSとJavaScriptで、簡単に使えるタブメニューを作りたいなと思いました。
実際、簡単になっているかはわかりません。
スタイルを自由に変更できるようにしたかったので、その観点を重視してみました。
環境
HTML, CSS, JavaScript
(レイアウト用にBootstrap5.0を使ってます)
表示結果
ヘッダーをクリックすると、ボディーの表示内容が変わるシンプルなメニューです。
HTML
Bootstrapの読み込みとかは抜いてます。
ヘッダーとボディーに data-tab-id
属性を付け、同じ値で対応させます。
<body class="container-fluid h-h100 bg-light">
<div class="row center-align" style="height: 5%;">
<!-- タブヘッダー -->
<div id="tab-head-parent" class="col-5 h-h100 center-align">
<div data-tab-id="1" class="tab-head-card h-h100 center-align" style="width: 15%;">Tab-A</div>
<div class="h-h100" style="width: 2.5%;"></div>
<div data-tab-id="2" class="tab-head-card disable-tab-head h-h100 center-align" style="width: 15%;">Tab-B</div>
<div class="h-h100" style="width: 2.5%;"></div>
<div data-tab-id="3" class="tab-head-card disable-tab-head h-h100 center-align" style="width: 15%;">Tab-C</div>
</div>
</div>
<div class="row center-align" style="height: 20%;">
<div class="col-5 h-h100">
<!-- タブボディー -->
<div data-tab-id="1" class="w-w100 h-h100 tab-body-card center-align">Tab-A-body</div>
<div data-tab-id="2" class="w-w100 h-h100 tab-body-card center-align" style="display: none;">Tab-B-body</div>
<div data-tab-id="3" class="w-w100 h-h100 tab-body-card center-align" style="display: none;">Tab-C-body</div>
</div>
</div>
</body>
CSS
上3つがタブ用で、.w-w100
からはおまけです。
/* ======= タブヘッダー用 ======= */
.tab-head-card {
border-radius: 0.75em 0.75em 0 0;
background-color: rgba(255, 127, 0, 1);
cursor: pointer;
transition: .2s;
}
/* ======= 無効なタブヘッダー用 ======= */
.disable-tab-head {
opacity: 0.5;
}
/* ======= タブ本体用 ======= */
.tab-body-card {
border-radius: 0 0 0.75em 0.75em;
border-top: 0.15em solid rgba(255, 127, 0, 1);
background-color: rgba(255, 255, 255, 1);
box-shadow: 0 0.15rem 0.4rem 0.05rem rgba(0, 0, 0, 0.1), 0 0 0.02rem rgba(0, 0, 0, 0.1);
transition: .2s;
}
/* 幅100% */
.w-w100 {
width: 100%;
}
/* 高さ100% */
.h-h100 {
height: 100%;
}
/* 縦横中央揃え */
.center-align {
display: flex;
justify-content: center;
align-items: center;
}
/* 縦中央、左揃え */
.vcenter-align {
display: flex;
align-items: center;
}
JavaScript
まず、ヘッダーの親要素に対するクリックイベントを拾います。
そして、HTMLで付与したdata-tab-id
属性を使って、target
からどれをクリックしたのかを探ります。
表示形式によっては、最後に捜査しているdisplayをblockに変えるか、変数にしてもよいですね。
document.getElementById('tab-head-parent').addEventListener('click', ev => {
const el = ev.target;
if (el.hasAttribute('data-tab-id')) {
let tabId;
let tabEnableId = el.getAttribute('data-tab-id');
// ヘッダーの表示切替
document.querySelectorAll('.tab-head-card').forEach((tabHeadDoc) => {
tabId = tabHeadDoc.getAttribute('data-tab-id');
if (tabId === tabEnableId) {
tabHeadDoc.classList.remove('disable-tab-head');
} else {
tabHeadDoc.classList.add('disable-tab-head');
}
});
// 本体の表示切替
document.querySelectorAll('.tab-body-card').forEach((tabBodyDoc) => {
tabId = tabBodyDoc.getAttribute('data-tab-id');
if (tabId === tabEnableId) {
tabBodyDoc.style.display = 'flex';
} else {
tabBodyDoc.style.display = 'none';
}
});
}
});
所感?
タブメニューを解説している方はたくさんいらっしゃると思います。
その点からもあまり有用ではないかもしれませんが、わりとまとまったかなと思うので
ご参考になれば幸いです。