タブメニューの実装解説|Tab Menu CSS & JS Guide

タブメニュー デザイン見本

タブをクリック(またはホバー)して表示内容を切り替えるタブメニューの実装デモ。コピーしてすぐに使えるHTML・CSS・JSのコードを掲載しています。

① クリック — タブをクリックで表示を切り替える

Tab 1
Tab 2
Tab 3

Tab 1 の内容です。

クリックでタブを切り替えてください。

Tab 2 の内容です。

テキストや画像を自由に配置できます。

Tab 3 の内容です。

複数の情報を整理して表示できます。

選択中のタブ: Tab 1

HTML
<div class="tab-container">
  <ul>
    <li class="selected" data-id="tab-1">Tab 1</li>
    <li data-id="tab-2">Tab 2</li>
    <li data-id="tab-3">Tab 3</li>
  </ul>
  <div class="tab-content selected" id="tab-1">
    タブ1のコンテンツです。
  </div>
  <div class="tab-content" id="tab-2">
    タブ2のコンテンツです。
  </div>
  <div class="tab-content" id="tab-3">
    タブ3のコンテンツです。
  </div>
</div>
CSS
.tab-container ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
}
.tab-container ul li {
  width: 100%;
  padding: 10px 16px;
  text-align: center;
  cursor: pointer;
  border-bottom: 3px solid transparent;
  transition: border-color 0.2s, color 0.2s;
}
.tab-container ul li.selected {
  color: #2563eb;
  border-bottom-color: #2563eb;
  font-weight: 700;
}
.tab-container ul li:not(.selected):hover {
  opacity: 0.6;
}
.tab-content {
  display: none;
  padding: 20px;
  border: 1px solid #e2e8f0;
  border-top: none;
}
.tab-content.selected {
  display: block;
}
JS
const tabItems = document.querySelectorAll('.tab-container ul li');
const tabContents = document.querySelectorAll('.tab-container .tab-content');

tabItems.forEach(item => {
  item.addEventListener('click', () => {
    tabItems.forEach(t => t.classList.remove('selected'));
    tabContents.forEach(c => c.classList.remove('selected'));
    item.classList.add('selected');
    document.getElementById(item.dataset.id).classList.add('selected');
  });
});
selected クラスで表示・非表示を切り替える仕組み

タブのコンテンツは初期状態で display: none にしておき、selected クラスが付いたものだけ display: block で表示します。タブをクリックすると、まず全タブと全コンテンツから selected を除去し、クリックされたタブと data-id に対応するコンテンツにだけ selected を付与します。このパターンは1つの要素しか表示しない「排他制御」の基本形で、モーダルやアコーディオンにも応用できます。

② ホバー — マウスホバーで表示を切り替える

Tab 1
Tab 2
Tab 3

Tab 1 の内容です。

タブにマウスを乗せて切り替えてください。

Tab 2 の内容です。

Tab 3 の内容です。

ホバー中のタブ: Tab 1

HTML
<div class="tab-container">
  <ul>
    <li class="selected" data-id="tab-1">Tab 1</li>
    <li data-id="tab-2">Tab 2</li>
    <li data-id="tab-3">Tab 3</li>
  </ul>
  <div class="tab-content selected" id="tab-1">
    タブ1のコンテンツです。
  </div>
  <div class="tab-content" id="tab-2">
    タブ2のコンテンツです。
  </div>
  <div class="tab-content" id="tab-3">
    タブ3のコンテンツです。
  </div>
</div>
CSS
.tab-container ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
}
.tab-container ul li {
  width: 100%;
  padding: 10px 16px;
  text-align: center;
  cursor: pointer;
  border-bottom: 3px solid transparent;
  transition: border-color 0.2s, color 0.2s;
}
.tab-container ul li.selected {
  color: #2563eb;
  border-bottom-color: #2563eb;
  font-weight: 700;
}
.tab-content {
  display: none;
  padding: 20px;
  border: 1px solid #e2e8f0;
  border-top: none;
}
.tab-content.selected {
  display: block;
}
JS
const tabItems = document.querySelectorAll('.tab-container ul li');
const tabContents = document.querySelectorAll('.tab-container .tab-content');

tabItems.forEach(item => {
  item.addEventListener('mouseover', () => {
    tabItems.forEach(t => t.classList.remove('selected'));
    tabContents.forEach(c => c.classList.remove('selected'));
    item.classList.add('selected');
    document.getElementById(item.dataset.id).classList.add('selected');
  });
});
mouseover イベントでホバー切り替えを実現する

click の代わりに mouseover イベントを使うだけで、マウスを乗せた瞬間にタブが切り替わります。mouseover はカーソルが要素の上に来るたびに発火します。なお、子要素があると子要素からの移動でも発火する場合があるため、子要素を持つ複雑な構造の場合は mouseenter イベントの使用も検討してください。

③ レスポンシブ — 画面サイズで縦横レイアウトを自動調整する

Tab 1
Tab 2
Tab 3

Tab 1 の内容です。

PC幅では横並び、SP幅では縦並びに切り替わります。

Tab 2 の内容です。

Tab 3 の内容です。

表示モード: PC幅(481px超)

HTML
<div class="tab-container">
  <ul>
    <li class="selected" data-id="tab-1">Tab 1</li>
    <li data-id="tab-2">Tab 2</li>
    <li data-id="tab-3">Tab 3</li>
  </ul>
  <div class="tab-content selected" id="tab-1">
    タブ1のコンテンツです。
  </div>
  <div class="tab-content" id="tab-2">
    タブ2のコンテンツです。
  </div>
  <div class="tab-content" id="tab-3">
    タブ3のコンテンツです。
  </div>
</div>
CSS
.tab-container ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
}
.tab-container ul li {
  width: 100%;
  padding: 10px 16px;
  text-align: center;
  cursor: pointer;
  border-bottom: 3px solid transparent;
  transition: border-color 0.2s, color 0.2s;
}
.tab-container ul li.selected {
  color: #2563eb;
  border-bottom-color: #2563eb;
  font-weight: 700;
}
.tab-container ul li:not(.selected):hover {
  opacity: 0.6;
}
.tab-content {
  display: none;
  padding: 20px;
  border: 1px solid #e2e8f0;
  border-top: none;
}
.tab-content.selected {
  display: block;
}

@media (max-width: 600px) {
  .tab-container ul {
    flex-direction: column;
  }
  .tab-container ul li {
    border-bottom: 1px solid #e2e8f0;
    border-left: 3px solid transparent;
    text-align: left;
  }
  .tab-container ul li.selected {
    color: #2563eb;
    border-left-color: #2563eb;
    border-bottom-color: #e2e8f0;
  }
  .tab-content {
    border-top: 1px solid #e2e8f0;
  }
}
JS
const tabItems = document.querySelectorAll('.tab-container ul li');
const tabContents = document.querySelectorAll('.tab-container .tab-content');

tabItems.forEach(item => {
  item.addEventListener('click', () => {
    tabItems.forEach(t => t.classList.remove('selected'));
    tabContents.forEach(c => c.classList.remove('selected'));
    item.classList.add('selected');
    document.getElementById(item.dataset.id).classList.add('selected');
  });
});
@media クエリで縦横レイアウトを自動調整する

タブの横並びは display: flex で実現しています。@media (max-width: 600px) の中で flex-direction: column に切り替えると、タブが縦積みに変わります。あわせてアクティブ表示のインジケーターを border-bottom から border-left に変えることで、縦並びでも選択状態が視覚的にわかりやすくなります。JSのロジックはクリック版と同じため、変更は不要です。


当サイトで公開しているWebデザインやUIの実装例は、一覧として以下記事に纏めています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次