MENU
カテゴリー
だいち
このブログの管理者
異業種で仕事をしながら、副業でWeb制作をしているアラサーリーマンです。
日々の勉強の記録や、お役立ち情報を発信していきます。
ホームページ制作などのお仕事に関するご依頼やご相談は、運営者情報のお問い合わせフォームかSNSのDMにて宜しくお願いします。

【jQuery】タブメニューの作り方をコード付きで解説

タブメニューの作り方を解説

どうも、ダイチです。

今回はWebサイトで多く使用されるUIデザインの一つ、タブメニューの実装方法をまとめました。

いまいち仕組みが分かってないのでコーディングにつまずいてる、なんて方もいるかと思いますが、当記事で紹介するコードはコピペもできるようにしています。

簡単に解説も入れているので、コーディングの参考にしたい方は是非ご覧ください。

それではいってみましょう!

目次

タブメニューとは

下のGif画像のように、タブ形状のメニューをホバーやクリック、タップすることでコンテンツが切り替わるUIのことです。

Image from Gyazo

料金メニューをプラン別に切り替えて表示させたり、ヘッダーメニューをホバーして切り替えたりと、省スペースで情報を制御できる汎用性の高いデザインです。

今回は3パターン作成していきます。デモページも用意しているので、完成版はこちらからご覧ください。

タブメニューをhoverで切り替え

HTML

<nav class="wrap">
    <ul class="tab-container">
      <li class="tab current">メニュー1</li>
      <li class="tab">メニュー2</li>
      <li class="tab">メニュー3</li>
      <li class="tab">メニュー4</li>
    </ul>
    <div>
      <ul class="menu-box">
        <li class="menu">メニュー1-1</li>
        <li class="menu">メニュー1-2</li>
        <li class="menu">メニュー1-3</li>
        <li class="menu">メニュー1-4</li>
      </ul>
      <ul class="menu-box">
        <li class="menu">メニュー2-1</li>
        <li class="menu">メニュー2-2</li>
        <li class="menu">メニュー2-3</li>
        <li class="menu">メニュー2-4</li>
      </ul>
      <ul class="menu-box">
        <li class="menu">メニュー3-1</li>
        <li class="menu">メニュー3-2</li>
        <li class="menu">メニュー3-3</li>
        <li class="menu">メニュー3-4</li>
      </ul>
      <ul class="menu-box">
        <li class="menu">メニュー4-1</li>
        <li class="menu">メニュー4-2</li>
        <li class="menu">メニュー4-3</li>
        <li class="menu">メニュー4-4</li>
      </ul>
    </div>
  </nav>

タブ領域としてulタグにtab-containerクラスでliタグにtabクラス、メニュー領域のulタグにはmenu-boxクラスでliタグにはmenuクラスを設定しました。

また、一つ目のタブにはcurrentクラスをつけていること、menu-boxの親要素としてdivタグで包んでいることはそれぞれ後ほど説明します。

CSS

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  list-style: none;
}

@media screen and (max-width: 600px) {
  body {
    font-size: 2.5vw;
  }
}


.wrap {
  padding-top: 3rem;
  width: 90%;
  max-width: 1000px;
  margin: 0 auto;
}

/************* 共通スタイルここまで **************/
/************* タブ *************/
.tab-container {
  display: flex;
  border-bottom: 3px double #2e2d2d
}

.tab {
  position: relative;
  padding: 1em;
  border-radius: 10px 10px 0 0;
  background-color: #ddd;
  transition: all .2s;
  cursor: pointer;
}

.tab:not(:last-of-type) {
  margin-right: 1em;
}

/* タブ現在値 */
.current {
  color: #eaeaea;
  background-color: #3972a7;
}

.current::before {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 3px;
  background-color: #28295e;
}

/************* メニュー *************/
.menu-box {
  width: 100%;
}

.menu {
  padding: 2em 1em;
  background-color: #eee;
  transition: all .2s;
  cursor: pointer;
}

※hoverのスタイルは割愛してます。

ここまででこんな感じになっているかと思います。

タブメニュー イメージ

一つ目のタブにcurrentクラスを設けていますが、これは今開いているタブのスタイルの為のクラスなので、jQueryで付け替えることになります。

jQuery

$(function () {
  //////////// 一番目以外のコンテンツは非表示
  $(".menu-box:not(:first-of-type)").css("display", "none");

  //////////// タブの制御
  $('.tab').hover(function () { // タブメニューをhoverしたら
    var index = $('.tab').index(this); // hoverしたタブ番号を取得
    $('.tab').removeClass('current'); // タブ現在地クラスを削除し、
    $(this).addClass('current'); // hoverしたタブにタブ現在地クラスを付与

    //////////// コンテンツの制御
    $('.menu-box').hide().eq(index).show(); // hoverしてないコンテンツは非表示、hoverした番号は表示
  });
});

一行ずつ分解して解説します。

$(".menu-box:not(:first-of-type)").css("display", "none");

一つ目は初めから表示させておくので、.menu-boxの内一番目以外をdisplay:noneで非表示するという内容を先に記述しています。これはCSSに書いてもいいですが、今回はjQuery制御します。

ちなみに先ほどHTMLの項で4つのmenu-boxクラスをdivで囲っていたのはこれが理由です。タブメニューの話とは逸れますが一応解説しておきます。興味の無い方は読み飛ばしてもらって大丈夫です。


今回のHTML構造の場合、もしdivで囲わなかった場合の階層は下のようになります。

<nav class="wrap">
    <ul class="tab-container"> <!-- 略 --> </ul>
    <ul class="menu-box"> <!-- 略 --> </ul>
    <ul class="menu-box"> <!-- 略 --> </ul>
    <ul class="menu-box"> <!-- 略 --> </ul>
    <ul class="menu-box"> <!-- 略 --> </ul>
</nav>

first-of-typeはクラスではなく要素に対して判定されるので、今回はmenu-boxクラスがついてる要素→ulタグと判定します。

その判定された要素の兄弟要素内にあるulタグの一番目にスタイル指定がされることになります。

.menu-box:not(:first-of-type) {
  display: none;
}

この場合一番目のulタグは.tab-containerクラスがついてるulタグです。これに指定されることになってしまい、それ以外のulタグにdisplay: noneがかかってしまいます。

全てのコンテンツにdisplay noneがかかっている画像

なので下記のようにulタグの階層をズラすことでクリアされる、ということです。(そもそもtab-containerクラスの要素がulタグじゃなければこんなことしなくてもいいです)

<nav class="wrap">
    <ul class="tab-container"> <!-- 略 --> </ul>
    <div>
      <ul class="menu-box"> <!-- 略 --> </ul>
      <ul class="menu-box"> <!-- 略 --> </ul>
      <ul class="menu-box"> <!-- 略 --> </ul>
      <ul class="menu-box"> <!-- 略 --> </ul>
    </div>
</nav>

hoverメソッドを使って、tabクラスの要素をhoverした時に〜する、という記述を書いていきます。

$('.tab').hover(function () { 

タブの装飾

タブメニューは表示されてるメニュー(コンテンツ)と連動して「今何番目のタブが選択されているか?」が分かるように装飾される事が殆どです。

hoverしたタブのインデックス番号を取得して変数indexに代入します。

var index = $('.tab').index(this);

タブをhoverしたら予め一番目のタブにつけているcurrentクラスを外します。

$('.tab').removeClass('current'); 

hoverしたタブに現在地クラスcurrentを付与します。

$(this).addClass('current'); 

メニュー(コンテンツ)の制御

hoverしてないコンテンツは非表示、hoverしたコンテンツは表示するという内容です。

$('.menu-box').hide().eq(index).show();

メソッドチェーンを使って書いてるので分解すると下記の通り。

$('.menu-box').hide();
$('.menu-box').eq(index).show();
  1. menu-boxはhideで非表示
  2. hoverしたタブのindex番号と同じmenu-box番号を表示させる

これで完成になります。

タブメニューをclickでフェード切り替え

GIFにすると分かりづらくなってしまいましたが、、、タブはクリックで切り替えて、その際にフワッと表示させる演出を加えます。(デモを見てもらった方が良いかもしれないです)

Image from Gyazo

大枠のコードはほとんど変わりません。

HTMLではmenu-boxの親要素で設定していたdivタグにmenu-containerという名前でクラスをつけます。

<div class="menu-container">
   <ul class="menu-box"> <!-- 略 --> </ul>
   <ul class="menu-box"> <!-- 略 --> </ul>
   <ul class="menu-box"> <!-- 略 --> </ul>
   <ul class="menu-box"> <!-- 略 --> </ul>
</div>

CSSは下記を追記してください。

menu-containerにposition: relative、menu-boxにposition: absoluteで位置を重ね合わせます。

/* メニュー */
.menu-container {
  /* fadein・outのために指定 */
  position: relative;
}

.menu-box {
  width: 100%;
  /* fadein・outのために指定 */
  position: absolute;
  top: 0;
}

jQueryは6行目をクリックイベントに変えて、十二行目のshowメソッドをfadeInメソッドに変えただけです。

fadeInの()内に数値を指定すれば表示される感じ(フワッと出てくるスピード)を変えられます。

$(function () {
  //////////// 一番目以外のコンテンツは非表示
  $(".menu-box:not(:first-of-type)").css("display", "none");

  //////////// タブの制御
  $('.tab').on('click', function () { // タブメニューをhoverしたら
    var index = $('.tab').index(this); // hoverしたタブ番号を取得
    $('.tab').removeClass('current'); // タブ現在地クラスを削除し、
    $(this).addClass('current'); // hoverしたタブにタブ現在地クラスを付与

    //////////// コンテンツの制御
    $('.menu-box').hide().eq(index).fadeIn();
  });
});

ちなみに前項のコードのまま(hoverメソッド)でフェード指定をすると、タブから外れるたびにmenuが一瞬消えてしまいます。

フェードで切り替えたい場合は、position指定する必要があるので注意が必要です。

タブメニューをclickでスライド切り替え

メニューをスライド形式で表示させます。

Image from Gyazo

こちらは先ほどの内容と比べて記述内容がかなり変わってきますが、原理については以前書いたカルーセルスライダーの記事で細かく解説してるので、詳細を確認したい方は良かったらこちらからご覧ください。

あわせて読みたい
【プラグインなし】カルーセルスライダーの作り方を解説(jQuery)
【プラグインなし】カルーセルスライダーの作り方を解説(jQuery)どうも、ダイチです。今回はカルーセルスライダー(カルーセルパネル)の作り方をまとめます。jsプラグインで簡単に実装できてしまうUIではありますが、思う挙動になら...

ざっくりとだけ説明すると、コンテンツ(メニュー)領域の階層を「表示枠」「横並びにしたスライドのレール」「スライド」と3つに分けます。

<div class="menu-wrap">
  <div class="menu-container">
    <ul class="menu-box"> <!-- 略 --> </ul>
    <ul class="menu-box"> <!-- 略 --> </ul>
    <ul class="menu-box"> <!-- 略 --> </ul>
    <ul class="menu-box"> <!-- 略 --> </ul>
  </div>
</div>
スライドイメージ
スライドのクラスイメージ図

分かりづらいかもしれないので全体も載せておきます。

<nav class="wrap">
    <ul class="tab-container">
      <li class="tab current">メニュー1</li>
      <li class="tab">メニュー2</li>
      <li class="tab">メニュー3</li>
      <li class="tab">メニュー4</li>
    </ul>
    <div class="menu-wrap">
      <div class="menu-container">
        <ul class="menu-box">
          <li class="menu">メニュー1-1</li>
          <li class="menu">メニュー1-2</li>
          <li class="menu">メニュー1-3</li>
          <li class="menu">メニュー1-4</li>
        </ul>
        <ul class="menu-box">
          <li class="menu">メニュー2-1</li>
          <li class="menu">メニュー2-2</li>
          <li class="menu">メニュー2-3</li>
          <li class="menu">メニュー2-4</li>
        </ul>
        <ul class="menu-box">
          <li class="menu">メニュー3-1</li>
          <li class="menu">メニュー3-2</li>
          <li class="menu">メニュー3-3</li>
          <li class="menu">メニュー3-4</li>
        </ul>
        <ul class="menu-box">
          <li class="menu">メニュー4-1</li>
          <li class="menu">メニュー4-2</li>
          <li class="menu">メニュー4-3</li>
          <li class="menu">メニュー4-4</li>
        </ul>
      </div>
    </div>
  </nav>

menu-boxを横に並べて、それをmenu-containerとして包みます。タブメニューとして表示されている領域はmenu-wrapクラスということになります。

.wrap {
  padding-top: 3rem;
  width: 90%;
  max-width: 1000px;
  margin: 0 auto;
  overflow: hidden;
}

.menu-wrap {
  width: 1000px;
  height: calc(1000px * 0.5625);
  position: relative;
}

.menu-container {
  position: absolute;
  height: 100%;
}

.menu-box {
  width: 1000px;
  height: 100%;
  float: left;
}

.menu {
  width: 100%;
  max-width: 1000px;
  padding: 2em 1em;
  background-color: #eee;
  transition: all .2s;
  cursor: pointer;
}

menu-boxはfloatで横並びにしているので画面外まではみ出し、横スクロールが発生しますので、wrapクラスにはoverflow: hiddenを指定しています。

あとはmenu-wrapをposition: relative、menu-containerをposition: absoluteにしないといけません。

また、それぞれの項目にwidthを指定する必要があるので追加しています。menu-containerはmenu-boxの幅×スライド数の合計幅になるので、計算してここで指定してもいいんですが、前回カルーセル記事で紹介している通りjQueryで計算して代入することにします。

///// コンテンツ全体の合計幅を計算
  var width = $('.menu-box').outerWidth(true); // menu-box1枚分の幅
  var length = $('.menu-box').length; // .menu-boxの数
  var totalWidth = width * length; // レール全体幅 = menu-box1枚の幅 × スライド合計数
// .menu-containerに合計の幅を代入(※タブ数が増えた時のためCSSで指定しない)
  $('.menu-container').css('width', totalWidth);

////////////////// タブの制御 //////////////////
  $('.tab').on('click', function () { 
    ///// タブの装飾
    var index = $('.tab').index(this); // クリックしたタブ番号を取得
    $('.tab').removeClass('current'); // タブ現在地クラスを削除し、
    $(this).addClass('current'); // クリックしたタブにタブ現在地クラスを付与

    ///// コンテンツがスライドする動き
    var carousel = function () { // 「carousel」という関数を定義
      $('.menu-container').stop().animate({    // レール全体を左に動かす関数
        left: index * -width   // スライド数 × menu-box1枚分の幅を左に動かす
      });
    }
    carousel();   // 「carousel」関数を実行
  });

1~6行目ではmenu-containerの幅を計算し、CSSメソッドで代入しています。

15〜21行目ではcarouselという名前で関数を組んでスライドの動きを実行しています。

動かすのはanimate関数で、menu-boxの幅を代入した変数widthの長さ分左に動かすようにしています。

これでメニューがスライドするタブメニュー の完成です。

まとめ

いかがでしたしょうか?

メニューを表示させるアニメーションに凝らなければかなり簡単にできることが分かるかと思います。

この機会にコードをストックして使いまわせるようにしておきましょう。

それでは今回はこのへんで!

タブメニューの作り方を解説

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

この記事を書いた人

異業種で仕事をしながら、副業でWeb制作をしているアラサーリーマンです。
日々の勉強の記録や、お役立ち情報を発信していきます。
ホームページ制作などのお仕事に関するご依頼やご相談は、運営者情報のお問い合わせフォームかSNSのDMにて宜しくお願いします。

コメント

コメントする

CAPTCHA


目次
閉じる