Web技術系中心に割と何でも更新中

【CSS・jQuery】タブ切り替え実装方法を3パターン紹介

Programming Web

疑問に思う人

Web制作者
「ページにタブ切り替えでコンテンツを表示させたいけど、どうやって実装すればいいんだろう?」

こういった悩みにお答えします。

本記事の内容

  • CSS・jQueryを使ったタブ切り替えの実装方法3パターン

こんにちは、mine(@mineblog7)です。

ブログ歴は4年、Web制作歴は7年ほどになります。
現在はmineblogを一人で運営しています。

Webサイトでは一つのページ内で複数のコンテンツを用意し、タブで表示を切り替える仕組みが採用されることがあります。いわゆるタブ切り替えを実装する機会があります。この記事では、タブ切り替えの代表的な実装の方法を紹介していきます。

基本的にタブ切り替えはCSSとjQueryを使用して実装することになりますが、仕組みさえ理解すれば比較的容易に実装できます。

タブ切り替え実装の基本的な考え方

この記事では、3つのタブで切り替えする方法を考えます。

動作イメージ

タブ切り替え動作イメージ

まず表示させるコンテンツと切り替えのためのタブをそれぞれ3つずつHTMLで組みます。CSSのみ、もしくはCSSとjQueryを組み合わせて、タブをクリックした際に、コンテンツ部分の要素の重なりの順番を変化させたり、要素の表示非表示を操作したりしてタブ切り替えを行います。

今回は、3種類の方法で見た目・動作ともに同じになるようにタブ切り替えを実装しました。

タブ切り替え実装方法

  • CSSのみ使用する方法(フラグメント識別子)
  • CSSのみ使用する方法(:targetとz-indexを使用)
  • CSSとjQueryを併用する方法

そのタブ切り替えを実装は本当に必要か?

タブ切り替えを実装するコンテンツがユーザーにとって重要ならば、タブ切り替えでコンテンツを隠さずに初めから表示させておくべきです。
SEO的にも、ユーザーにとって分かりやすくするという意味でも、本当に重要なコンテンツなら表示させておきましょう。

CSSのみ使用する方法(フラグメント識別子)

CSSのみでタブ切り替えを実現するメリットとしては、jQuery読み込み必要がないので動作が比較的早いという点、jQueryの知識が不要でお手軽という点です。

まずは、フラグメント識別子により疑似的に切り替える方法を紹介します。

フラグメント識別子

フラグメント識別子というと難しい言い方ですが、簡単に言うとページ内リンクを設置する際に、aタグでリンク先にhrefに指定するidのことを指します。

このフラグメント識別子によるページ内リンクを利用して、タブ切り替えを疑似的に実装する方法を紹介します。

HTML

<div id="demo1">
	<div class="tab_area clearfix">
		<ul>
			<li class="even"><a href="#contents1">タブ1</a></li>
			<li class="odd"><a href="#contents2">タブ2</a></li>
			<li class="even"><a href="#contents3">タブ3</a></li>  
		</ul>
	</div>
	<div class="content_area">
		<div class="content_area_inner clearfix">
			<div id="contents1" class="content_block">
				ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。
				ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。
			</div>
			<div id="contents2" class="content_block">
				ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。
				ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。
			</div>
			<div id="contents3" class="content_block">
				ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。
				ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。
			</div>
		</div>
	</div>
</div>

HTMLでタブを3つ、各タブに対応したコンテンツを3つそれぞれ組みます。

CSS

/*タブ部分*/
#demo1 .tab_area ul li{
	display:block;
	background:#dddddd;
	border-right:1px solid #ffffff;
	width: 100px;
	float:left;
	-webkit-box-sizing : border-box ;
	-moz-box-sizing : border-box ;
	box-sizing : border-box ;
}
 
#demo1 .tab_area ul li a{
	display:block;
	text-align:center;
	font-size:22px;
	padding: 5px;
	color:#313131;
}
 
#demo1 .tab_area ul li a:hover {
	background:#999999;
	color:#ffffff;
}
/*コンテンツ部分の表示領域を固定してはみ出さないようにする*/
#demo1 .content_area {
	width: 600px;
	overflow: hidden;
	height: 140px;
	font-size: 20px;
	border: 1px solid #DDDDDD;
}
 
/*コンテンツを1行にするために必要な幅をとる*/
#demo1 .content_area .content_area_inner {
	width:1800px;
}
/*コンテンツのスタイル設定*/
#demo1 .content_area .content_block {
	height: 140px;
	padding: 10px;
	width: 600px;
	float: left;
	-webkit-box-sizing : border-box ;
	-moz-box-sizing : border-box ;
	box-sizing : border-box ;
}
 
#demo1 #contents1 {
	background:#47CA40;
}
#demo1 #contents2 {
	background:#EBEF64;
}
#demo1 #contents3 {
	background:#F56B6B;
}

この方法では、コンテンツ表示領域を固定しています。
タブをクリックした時に、ページ内リンクを使って表示させたいコンテンツの場所にジャンプさせることで、表示が切り替わっているように見せています。

切り替えのタイミングで表示がずれないように3つのコンテンツの高さ・幅を統一しています

CSSのみ使用する方法(:targetとz-indexを使用)

ターゲット疑似クラスとはクリック時に、あるHTMLの要素に対してスタイルを与えるためのものです。

フラグメント識別子を使用した場合は、ページ内リンクで特定の場所に移動させていましたが、ターゲット疑似クラスでは、各コンテンツをすべて重ねて表示させ、タブクリック時に重なりの順番を変化させることでタブ切り替えを実現します。

<div id="demo2">
	<div class="tab_area clearfix">
		<ul>
			<li class="odd"><a href="#contents2_1">タブ1</a></li>
			<li class="even"><a href="#contents2_2">タブ2</a></li>
			<li class="odd"><a href="#contents2_3">タブ3</a></li> 
		</ul>
	</div>
	<div class="content_area">
		<div class="content_area_inner clearfix">
			<div id="contents2_1" class="content_block_2">
				ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。
				ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。
			</div>
			<div id="contents2_2" class="content_block_2">
				ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。
				ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。
			</div>
			<div id="contents2_3" class="content_block_2">
				ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。
				ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。
			</div>
		</div>
	</div>
</div>

この方法でも基本的には、フラグメント識別子を使用する方法と同様にHTMLを組みます。

CSS

#demo2 .tab_area ul li{
	display:block;
	float:left;
	background:#dddddd;
	width: 100px;
	border-right:1px solid #ffffff;
	-webkit-box-sizing : border-box ;
	-moz-box-sizing : border-box ;
	box-sizing : border-box ;
}
#demo2 .tab_area ul li a{
	display:block;
	text-align:center;
	font-size:22px;
	padding: 5px;
	color:#313131;
}
#demo2 .tab_area ul li a:hover {
	background:#999999;
	color:#ffffff;
}
#demo2 .content_area {
	width: 600px;
	overflow: hidden;
	height: 140px;
	font-size: 20px;
	border: 1px solid #DDDDDD;
	position: relative;
}
#demo2 .content_area .content_block {
	height: 140px;
	padding: 10px;
	width: 600px;
	-webkit-box-sizing : border-box ;
	-moz-box-sizing : border-box ;
	box-sizing : border-box ;
}
.content_block_2 {
	position:absolute;
	left:0;
	top:0;
	padding: 10px;
}
#contents2_1 {
	background:#47CA40;
	z-index:1;
}
#contents2_2 {
	background:#EBEF64;
	z-index:0;
}
#contents2_3 {
	background:#F56B6B;
	z-index:0;
}
#contents2_1:target,
#contents2_2:target,
#contents2_3:target {
	z-index:100;
}

この方法では、3つのコンテンツをposition:absolute;を使い、同じ場所に表示させるようにしています。

初めは緑色の背景のcontent2_1を一番上に表示させるためにz-index:1;を設定します。

タブをクリックした時にCSSでターゲット疑似クラス(:target)を利用して3つのコンテンツのz-indexの値を変えることで表示の切り替えを行います。

CSSとjQueryを併用して実装する方法

CSSとjQueryを併用する方法は、仕組みが分かりやすく、より複雑なタブ切り替えに対応しうる点がメリットとして挙げられます。

仕組みとしては、タブをクリックした時に、クリックしたタブと関連づいた要素をdisplay:block(表示)の状態にして、それ以外をdisplay:none(非表示)にするという動作をjQueryで実現します。

<div id="demo3">
	<div class="tab_area clearfix">
		<ul>
			<li class="even">タブ1</li>
			<li class="odd">タブ2</li>
			<li class="even">タブ3</li>
		</ul>
	</div>
	<div class="content_area">
		<div class="content_area_inner clearfix">
			<div id="contents3_1" class="content_block_3" style="display:block">
				ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。
				ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。ここはタブ1をクリックした時に表示されます。
			</div>
			<div id="contents3_2" class="content_block_3" style="display:none">
				ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。
				ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。ここはタブ2をクリックした時に表示されます。
			</div>
			<div id="contents3_3" class="content_block_3" style="display:none">
				ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。
				ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。ここはタブ3をクリックした時に表示されます。
			</div>
		</div>
	</div>
</div>

この方法でも基本的にはCSSのみを使った方法と同様にHTMLを組みます。

CSS

/*タブ部分*/
#demo3 .tab_area ul li{
	display:block;
	float:left;
	background:#dddddd;
	width: 100px;
	border-right:1px solid #ffffff;
	-webkit-box-sizing : border-box ;
	-moz-box-sizing : border-box ;
	box-sizing : border-box ;
	text-align:center;
	font-size:22px;
	padding: 5px;
	color:#313131;
}
#demo3 .tab_area ul li:hover {
	background:#999999;
	color:#ffffff;
	cursor:pointer;
}
/*コンテンツ部分の表示領域を固定してはみ出さないようにする*/
#demo3 .content_area {
	width: 600px;
	overflow: hidden;
	height: 140px;
	font-size: 20px;
	border: 1px solid #DDDDDD;
	position: relative;
}
#demo3 .content_area .content_block {
	height: 140px;
	padding: 10px;
	width: 600px;
	-webkit-box-sizing : border-box ;
	-moz-box-sizing : border-box ;
	box-sizing : border-box ;
}
.content_block_3 {
	background: #ffffff;
	padding: 10px;
}
#contents3_1 {
	background:#47CA40;
}
#contents3_2 {
	background:#EBEF64;
}
#contents3_3 {
	background:#F56B6B;
}

コンテンツの表示領域だけを設定して、ブロック要素を単純に縦に並べています。

jQuery

$(function() {
	//タブクリック時の処理
	$('#demo3 .tab_area ul li').click(function() {
		//.index()を使いクリックされたタブの順番を変数indexに代入する
		var index = $('#demo3 .tab_area ul li').index(this);
		//指定した全コンテンツを非表示にする
		$('.content_block_3').css('display','none');
		//クリックされたタブと同じ順番のコンテンツのみを表示させる
		$('.content_block_3').eq(index).css('display','block');
	});
});

タブをクリックした時に、クリックしたタブの順番を取得すると同時に、一度コンテンツ要素全てをdisplay:none;で非表示にします。

クリックしたタブの順番に対応する要素にだけdisplay:block;を適用して表示させています。

まとめ

Webページ上でタブ切り替えを実装する方法は、どの方法が一番良いというのは無くて、環境や条件に最適なものを選んでください。

なぜこれで正しく動作するのかということをしっかりと理解しておくことで、動作の追加・ビジュアルの変更などの細かいカスタマイズに対応しやすくなると思います。

個人的には、CSS+jQueryを併用したタブ切り替え実装のほうがデザイン的にも動作的にも自由度が高いという点でおすすめですね。

おすすめ記事 【体験談】弁護士の退職代行で有給30日分を取得した話

おすすめ記事 「知らないから落ちる面接の4点減点法」で面接に挑んだ結果