【JS&CSS】クリックやホバーで表示を切り替える(タブメニュー)

【メイン画像】タブメニューを実装する方法

タイトルなどの見出し(タブ)をクリック または マウスホバーすると、それに応じた内容を表示させる『タブメニュー』の実装方法(HTML/CSS/JavaScriptコード)を、実装例とともに紹介します。

目次

実装例とコード

クリック(タップ)で表示が変わるパターンと、マウスホバーで表示が変わるパターンの2種を実装しました。 
実際にタブをクリック(タップ)またはホバーしてみてください。

クリックで表示を切り替える

HTML / CSS / JavaScript コード
<div class="tab-container">
  <ul>
    <li class="selected" data-id="tab-1">タブ1</li>
    <li data-id="tab-2">タブ2</li>
    <li data-id="tab-3">タブ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>
.tab-container ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
}

.tab-container ul li {
  width: 100%;
  padding: 8px 16px;
}

.tab-container ul li.selected {
  color: white;
  background-color: black;
}

/* 選択されていないタブは、カーソルをポインター表示にする。*/
.tab-container ul li:not(.selected) {
  cursor: pointer;
}

/* 選択されていないタブは、ホバー時に半透明にする。*/
.tab-container ul li:not(.selected):hover {
  opacity: .6;
}

/* コンテンツを非表示。 */
.tab-content {
  display: none;
}

/* selectedクラスが付いたコンテンツのみ表示。 */
.tab-content.selected {
  display: block;
  border: 2px solid black;
  padding: 8px;
  min-height: 200px;
}
const tabMenuItems = document.querySelectorAll('.tab-container ul li');
const tabContents = document.querySelectorAll('.tab-container .tab-content');

tabMenuItems.forEach(tabMenuItem => {
  tabMenuItem.addEventListener('click', () => {

    // 全てのタブからselectedクラスを外す。
    tabMenuItems.forEach(tabMenuItem => {
      tabMenuItem.classList.remove('selected');
    });
    
    // クリックされたタブのみselectedクラスを付ける。
    tabMenuItem.classList.add('selected');
    
    // 全てのタブのコンテンツからselectedクラスを外す。
    tabContents.forEach(tabContent => {
      tabContent.classList.remove('selected');
    });

    // クリックされたタブのカスタムデータ属性と同じIDを持つコンテンツに、selectedクラスを付ける。
    // カスタムデータ属性については別記事で紹介しています。
    document.getElementById(tabMenuItem.dataset.id).classList.add('selected');
  });
});

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

HTML / CSS / JavaScript コード
<div class="tab-container">
  <ul>
    <li class="selected" data-id="tab-1">タブ1</li>
    <li data-id="tab-2">タブ2</li>
    <li data-id="tab-3">タブ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>
.tab-container ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
}

.tab-container ul li {
  width: 100%;
  padding: 8px 16px;
}

.tab-container ul li.selected {
  color: white;
  background-color: black;
}

/* コンテンツを非表示。 */
.tab-content {
  display: none;
}

/* selectedクラスが付いたコンテンツのみ表示。 */
.tab-content.selected {
  display: block;
  border: 2px solid black;
  padding: 8px;
  min-height: 200px;
}
const tabMenuItems = document.querySelectorAll('.tab-container ul li');
const tabContents = document.querySelectorAll('.tab-container .tab-content');

tabMenuItems.forEach(tabMenuItem => {
  // マウスホバー時に発火するイベントは「mouseover」を使う。
  tabMenuItem.addEventListener('mouseover', () => {

    // 全てのタブからselectedクラスを外す。
    tabMenuItems.forEach(tabMenuItem => {
      tabMenuItem.classList.remove('selected');
    });
    
    // クリックされたタブのみselectedクラスを付ける。
    tabMenuItem.classList.add('selected');
    
    // 全てのタブのコンテンツからselectedクラスを外す。
    tabContents.forEach(tabContent => {
      tabContent.classList.remove('selected');
    });

    // クリックされたタブのカスタムデータ属性と同じIDを持つコンテンツに、selectedクラスを付ける。
    // カスタムデータ属性については別記事で紹介しています。
    document.getElementById(tabMenuItem.dataset.id).classList.add('selected');
  });
});

実装のポイント

表示・非表示を切り替えるには

クリックなど、何らかのアクションによって表示・非表示を切り替えるには、display: block;display: none;を使い分けるのが代表的な方法です。

  • display: block;→ 表示(ブロック要素のデフォルト設定)
  • display: none;→ 非表示

本実装のように、予めdisplay: none;で非表示にしておいた要素に、クリックやホバーをトリガーとしてdisplay: block;を設定したクラスを付与することで、表示・非表示を切り替えられます。

以下記事で紹介している実装も、基本的にはこの応用になります。

要素を横並びにするには

通常、HTMLでブロック要素は縦に並んでいきますが、本実装例のタブのように、ブロック要素を横に並べたいときは「フレックスボックス」を使います。

具体的には、横に並べたいブロック要素を持つ親要素display: flex;を設定します。
これだけで、子に当たるブロック要素は、縦ではなく横に並ぶようになります。

フレックスボックスを使わない場合

1
2
3
4

フレックスボックスを使う場合

1
2
3
4

フレックスボックスを使うと、要素の感覚や配置順など、他にも様々なレイアウトを組むことができます。
詳しくは以下記事で解説していますので、合わせてご覧ください。

複数要素を連動させるには

『①のタブをクリック(ホバー)したら①のコンテンツ、②のタブをクリック(ホバー)したら②のコンテンツ』というように、要素同士を連携させるには、カスタムデータ属性を使う方法があります。

カスタムデータ属性とは

idやclassなどと同じhtmlの属性で、自分オリジナルの名前をつけられるという特徴があります。

<div data-◯◯="□□"></div>

のように使います。

この説明だけでは使いみちがよくわからないかと思いますが、詳細は以下記事で説明していますので、合わせてご覧ください。

【応用】お知らせ表示

タブメニューとモーダルウィンドウを組み合わせたお知らせ表示です。各お知らせをクリックすると、そのお知らせに合ったコンテンツがポップアップウィンドウ(モーダルウィンドウ)で表示されるのがポイントです。

  • お知らせ 1
  • お知らせ 2
  • お知らせ 3

お知らせに応じた内容が表示されます。

具体的な実装方法は以下記事で紹介していますので、ぜひ合わせてご覧ください。


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

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