WEBサイトでよく見かけるものにタブメニューがあります。
タブメニューはタブの部分をクリックすることにより、コンテンツ部分が切り替わります。
必要な情報だけを画面に表示することができるのでスペースの節約にもなるため、いろんなWEBサイトで使われています。
このタブメニューは「CSSとJQUERY」で作ったり、「CSS」だけでも作ることができます。
今回は「CSS」と「JQUERY」を使ったタブメニューと「CSS」だけを使ったタブメニューの作り方について書きたいと思います。
CSSとjQUERYを使ったタブメニュー
CSSとjQUERYをつかって以下のようなタブメニューを作ります。
See the Pen tab-menu1 by konpure (@yuntu) on CodePen.
HTML
<div class="tab">
<!-- タブメニュー -->
<ul class="tab-menu">
<li class="tab-item active">タブ1</li>
<li class="tab-item">タブ2</li>
<li class="tab-item">タブ3</li>
</ul><!-- /.tab_menu -->
<!-- コンテンツ -->
<div class="tab-box">
<div class="tab-content show">コンテンツ1</div>
<div class="tab-content">コンテンツ2</div>
<div class="tab-content">コンテンツ3</div>
</div>
</div>
HTMLを作成するときのポイントは
タブのメニューの順番とコンテンツの順番を一致させる
ように作成します。
具体的には
メニュー1、メニュー2、メニュー3、メニュー4
コンテンツ1、コンテンツ2、コンテンツ3、コンテンツ4
という感じにメニューと表示させたいコンテンツの順番が一致するように作成します。
なぜこのように作るのかというと、後ほどjQueryを使ってコンテンツを表示する仕組みをつくります。
その際にタブメニューの順番を取得して、その順番を使って同じ順番にあるコンテンツを表示させるので順番が一緒である必要があるわけです。
タブメニューはulタグとliタグを使ってタブ部分を作成しています。
選択中のタブにはactiveクラスをつけています。
表示されているコンテンツにはshowクラスをつけています。
jQueryでこれらのクラスの付け替えを行い、タブのデザインを変えたり、表示するコンテンツを切り替えるようにしています。
CSS
* {
box-sizing: border-box;
}
ul,
li {
padding: 0;
margin: 0;
}
li {
list-style: none;
}
.tab {
width: 500px;
max-width: 100%;
margin: auto;
}
.tab-menu {
display: flex;
}
.tab-item {
text-align: center;
padding: 10px 0;
cursor: pointer;
/* widthを同じ比率で分けあう */
flex-grow: 1;
/* 下線以外をつける */
border-top: 1px solid skyblue;
border-left: 1px solid skyblue;
border-right: 1px solid skyblue;
}
.tab-item:not(:first-child) {
border-left: none;
}
/* アクティブなタブはデザインを変えて選択中であることが解るようにする */
.tab-item.active {
background: red;
color: white;
}
.tab-box {
height: 200px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid skyblue;
}
/* コンテンツは原則非表示 */
.tab-content {
display: none;
font-size: 40px;
}
/* .showがついたコンテンツのみ表示 */
.tab-content.show {
display: block;
}
タブメニューのデザインにはFlexboxを使っています。
「flex-glow: 1」にすることで、各タブに均等に幅が割り当てられます。
またアクティブなタグとそれ以外のタグを区別するために「active」というクラスを付与し、アクティブなタブとそれ以外のタブではデザインが異なるようにしています。
コンテンツ部分は基本的にdisplay: noneで非表示とし、showというクラスがついたものだけを表示するようにしています。
このshowクラスの付け外しはjQueryで行います。
これにより1つのコンテンツだけが表示されます。
jQUERY
$(function() {
$('.tab-item').click(function() {
//現在activeが付いているクラスからactiveを外す
$('.active').removeClass('active');
//クリックされたタブメニューにactiveクラスを付与。
$(this).addClass('active');
//一旦showクラスを外す
$('.show').removeClass('show');
//クリックしたタブのインデックス番号取得
const index = $(this).index();
//タブのインデックス番号と同じコンテンツにshowクラスをつけて表示する
$('.tab-content').eq(index).addClass('show');
});
});
いずれかのタブがクリックされたのをきっかけにイベントを開始します。
まずタブがクリックされたら、アクティブなタブに付与されている「active」というクラスをremoveClassを使って一旦外します。
そして$(this).addClass('active')により、クリックされたタブに「active」クラスを付与してクリックされていないタブとは異なるデザインにします。
続いてコンテンツ部分の切り替え。
コンテンツを表示するためのshowというクラスをremoveClassにより一旦外します。
index()をつかってクリックされたタブの順番を取得します。
その取得したタブの順番と一致する順番のコンテンツにshowクラスを付与して表示します。
.eq()は要素の順番を指定するためのもので、引数にindex()で得た順番を入力しすることでタブと同じ順番のコンテンツを指定することができます。
以上がCSSとjQueryを利用して作成するタブメニューです。
CSSだけでタブメニューを作る
ラジオボタンを使うことでCSSだけでタブメニューを作ることもできます。
See the Pen tab-menu2 by konpure (@yuntu) on CodePen.
HTML
<div class="tab">
<!-- 初期状態で表示されるコンテンツに対応するラジオボタンにはchecked="checkedを設定する -->
<input id="menu1" class="tab-input" name="menu" type="radio" checked="checked">
<label for="menu1" class="tab-item">タブ1</label>
<div class="tab-content">コンテンツ1</div>
<input id="menu2" class="tab-input" name="menu" type="radio">
<label for="menu2" class="tab-item">タブ2</label>
<div class="tab-content">コンテンツ2</div>
<input id="menu3" class="tab-input" name="menu" type="radio">
<label for="menu3" class="tab-item">タブ3</label>
<div class="tab-content">コンテンツ3</div>
</div>
labelタグでタブメニューを作成しておりラジオボタンに紐づけられています。
タブメニューをクリックすると該当するラジオボタンにチェックが入ります。
CSSの:checkedを使うことによりラジオボタンのチェックの有無を確認して、コンテンツの表示・非表示の切り替えを行います。
初期状態で表示されるコンテンツに対応するラジオボタンにはchecked="checked"を設定し、であらかじめチェックが入っている状態にしておきます。
CSS
* {
box-sizing: border-box;
}
/* ラジオボタンは非表示 */
input[type="radio"] {
display: none;
}
.tab {
width: 500px;
max-width: 100%;
margin: auto;
display: flex;
flex-flow: wrap;
}
.tab-item {
display: block;
flex-grow: 1;
text-align: center;
padding: 10px 0;
cursor: pointer;
order: -1;/* タブメニューは一番上に表示する */
/* 下線以外をつける */
border-top: 1px solid skyblue;
border-left: 1px solid skyblue;
border-right: 1px solid skyblue;
}
.tab-item:not(:first-of-type) {
border-left: none;
}
/* アクティブなタブの背景色と文字色を変える */
.tab-input:checked + .tab-item {
background: red;
color: white;
}
/* コンテンツは原則非表示 */
.tab-content {
width: 100%;
height: 200px;
display: none;
justify-content: center;
align-items: center;
font-size: 40px;
border: 1px solid skyblue;
}
/* ラジオボタンがチェックされているコンテンツだけは表示 */
.tab-input:checked + .tab-item + .tab-content {
display: flex;
}
ラジオボタン自体は表示しませんのでdisplay:noneで消しておきます。
タブを一番上に表示するので、タブ部分のorderを-1にして一番上に表示するようにします。
そしてコンテンツも基本的には非表示にしておき、:checkedを使ってラジオボタンにチェックが入っているものだけ表示するようにします。
タブがクリックされると、そのタブと紐づけられているラジオボタンにはチェックが入ります。
ラジオボタンは複数の選択肢から1つを選択する役割を持っているので、他のタブをクリックするとラジオボタンのチェックも他に移ります。
その仕組みを利用して、:checkedでチェックの有無を確認してコンテンツを切り替えるようにしています。
セレクタの「+」は隣接セレクタで該当する要素の隣の要素を指定することができます。
つまり「.tab-input:checked + .tab-item + .tab-content」というのは、ラジオボタンがチェックされたら、その隣(タブメニュー)の隣(コンテンツ)に対してデザインが設定されるという意味合いを持っています。
今回は中の要素(コンテンツという文字)を中央寄せにしたかったので「display: flex」にしましたが、ただ表示するだけなら「display: block」で大丈夫です。
以上がCSSでのタブメニューの作り方です
まとめ
以上が「CSSとjQuery」または「CSSだけ」でタブメニューを作る方法です。
両者の大きな違いは
タブがクリックされたことの確認の方法
だと思います。
CSSとJQUERYの場合はタブがクリックされたことをjQueryを使って確認し、CSSの場合はラジオボタンを使って確認しています。
どちらの方法も覚えておいて、状況に応じて使い分けると良いと思います。
何かの参考になれば幸いです。