TECH

Vol.86

author

Y.M.

Simple Tab Switching Implementation

#WEB#HTML#webサイト#JavaScript
Last update : 2026.5.12
Posted : 2018.1.18
Tab-switching content allows users to switch between sections without large interactions such as page transitions or scrolling. Tabs can be implemented using CSS and JavaScript, or even with CSS alone. In this article, we’ll introduce some simple ways to create tab-switching functionality, complete with demos and sample code.
stuffstuff

Basic Implementation

We’ll implement tab-switching functionality using both CSS + JavaScript and CSS-only approaches.

Implementing Tabs with CSS Only

panel1

panel2

panel3

<div class="tab_wrap">
	<input id="tab1" type="radio" name="tab_btn" checked>
	<input id="tab2" type="radio" name="tab_btn">
	<input id="tab3" type="radio" name="tab_btn">

	<div class="tab_area">
		<label class="tab1_label" for="tab1">tab1</label>
		<label class="tab2_label" for="tab2">tab2</label>
		<label class="tab3_label" for="tab3">tab3</label>
	</div>
	<div class="panel_area">
		<div id="panel1" class="tab_panel">
			<p>panel1</p>
		</div>
		<div id="panel2" class="tab_panel">
			<p>panel2</p>
		</div>
		<div id="panel3" class="tab_panel">
			<p>panel3</p>
		</div>
	</div>
</div>

CSSのみで実装する際、ラジオボタンでコンテンツ切り替えの制御をします。
ラジオボタンとタブ用の要素(サンプルではlabel)を連動させるため、
連動させる要素にfor属性でラジオボタンのidを指定します。

..tab_wrap{width:500px; margin:80px auto;}
input[type="radio"]{display:none;}
.tab_area{font-size:0; margin:0 10px;}
.tab_area label{width:150px; margin:0 5px; display:inline-block; padding:12px 0; color:#999; background:#ddd; text-align:center; font-size:13px; cursor:pointer; transition:ease 0.2s opacity;}
.tab_area label:hover{opacity:0.5;}
.panel_area{background:#fff;}
.tab_panel{width:100%; padding:80px 0; display:none;}
.tab_panel p{font-size:14px; letter-spacing:1px; text-align:center;}

#tab1:checked ~ .tab_area .tab1_label{background:#fff; color:#000;}
#tab1:checked ~ .panel_area #panel1{display:block;}
#tab2:checked ~ .tab_area .tab2_label{background:#fff; color:#000;}
#tab2:checked ~ .panel_area #panel2{display:block;}
#tab3:checked ~ .tab_area .tab3_label{background:#fff; color:#000;}
#tab3:checked ~ .panel_area #panel3{display:block;}

「~」結合子について
同じ親要素を持つ兄弟要素を指定する際に使用します。
弟要素(隣接した後ろの要素)のみを指定する「+」結合子とは違い、先に指定した要素より後ろにある兄弟要素であればスタイルを適用することができます。

またCSSのみでの実装では、タブが選択された際のデザインなどは個別指定しなければなりません。
タブ数が多いと記述が長くなってしまいますが、Sassを使用すれば繰り返し処理で簡単に指定することができます。

Sass @whileとインターポレーションを使用した繰り返し処理の記述

$i:1;
$length:3;
@while $i <= $length{
	#tab#{$i}:checked{
		~ .tabarea1 .tab#{$i}_label{background:#fff; color:#000;}
		~ .panel_area #panel#{$i}{display:block;}
	}
	$i:$i + 1;
}

Implementing Tabs with CSS and JavaScript

panel1

panel2

panel3

.tab_wrap{width:500px; margin:80px auto;}
.tab_area{font-size:0; margin:0 10px;}
.tab_area label{width:150px; margin:0 5px; display:inline-block; padding:12px 0; color:#999; background:#ddd; text-align:center; font-size:13px; cursor:pointer; transition:ease 0.2s opacity;}
.tab_area label:hover{opacity:0.5;}
.panel_area{background:#fff;}
.tab_panel{width:100%; padding:80px 0; display:none;}
.tab_panel p{font-size:14px; letter-spacing:1px; text-align:center;}

.tab_area label.active{background:#fff; color:#000;}
.tab_panel.active{display:block;}
.tab_wrap{width:500px; margin:80px auto;}
.tab_area{font-size:0; margin:0 10px;}
.tab_area label{width:150px; margin:0 5px; display:inline-block; padding:12px 0; color:#999; background:#ddd; text-align:center; font-size:13px; cursor:pointer; transition:ease 0.2s opacity;}
.tab_area label:hover{opacity:0.5;}
.panel_area{background:#fff;}
.tab_panel{width:100%; padding:80px 0; display:none;}
.tab_panel p{font-size:14px; letter-spacing:1px; text-align:center;}

.tab_area label.active{background:#fff; color:#000;}
.tab_panel.active{display:block;}
$(".tab_label").on("click",function(){
	var $th = $(this).index();
	$(".tab_label").removeClass("active");
	$(".tab_panel").removeClass("active");
	$(this).addClass("active");
	$(".tab_panel").eq($th).addClass("active");
});

選択中のデザインはCSSを使用し、クラスの追加/削除をJSで制御します。
jQueryには toggleClass が存在しますが、jQuery3以降では非推奨タグとなっているため使用していません。

Changing the Design with border-radius

When creating layouts and designs, various properties are usually combined together.
This time, however, we’ll introduce ways to create visually rich tab designs using only border-radius, which rounds the corners of box elements.

Rounded corners are applied to parts of the tabs and content areas, creating a softer impression.

border and border-radius are combined to create borders that resemble hand-drawn lines.

The currently selected tab is styled as a perfect circle, while the content area uses larger rounded corners to create a cute and playful design.

Adding Animation

Next, we’ll implement animations for when tabs are clicked and the content changes.
Even simple animations make the transition feel clearer and more visually engaging.

Content Fades When Switching

CSSでの実装

panel1

panel2

panel3

@keyframes tabAnim{
  0%{opacity:0;}
  100%{opacity:1;}
}
.tab_wrap{width:500px; margin:80px auto;}
input[type="radio"]{display:none;}
.tab_area{font-size:0; margin:0 10px;}
.tab_area label{width:150px; margin:0 5px; display:inline-block; padding:12px 0; color:#999; background:#ddd; text-align:center; font-size:13px; cursor:pointer; transition:ease 0.2s opacity;}
.tab_area label:hover{opacity:0.5;}
.tab_panel{width:100%; opacity:0; padding:80px 0; display:none;}
.tab_panel p{font-size:14px; letter-spacing:1px; text-align:center;}
.panel_area{background:#fff;}
#tab1:checked ~ .tab_area .tab1_label{background:#fff; color:#000;}
#tab1:checked ~ .panel_area #panel1{display:block; animation:tabAnim ease 0.6s forwards; -ms-animation:tabAnim ease 0.6s forwards;}
#tab2:checked ~ .tab_area .tab2_label{background:#fff; color:#000;}
#tab2:checked ~ .panel_area #panel2{display:block; animation:tabAnim ease 0.6s forwards; -ms-animation:tabAnim ease 0.6s forwards;}
#tab3:checked ~ .tab_area .tab3_label{background:#fff; color:#000;}
#tab3:checked ~ .panel_area #panel3{display:block; animation:tabAnim ease 0.6s forwards; -ms-animation:tabAnim ease 0.6s forwards;}

CSS、JSでの実装

tab1 tab2 tab3

panel1

panel2

panel3

JSで制御するCSSの記述

.tab_area label.active{background:#fff; color:#000;}
.tab_panel.active{display:block; animation:tabAnim ease 0.6s forwards; -ms-animation:tabAnim ease 0.6s forwards;}

JSの記述

$(".tab_label").on("click",function(){
  var $th = $(this).index();
  $(".tab_label").removeClass("active");
  $(".tab_panel").removeClass("active");
  $(this).addClass("active");
  $(".tab_panel").eq($th).addClass("active");
});

Content Slides Down from the Top

CSSでの実装

tab1 tab2 tab3

panel1

panel2

panel3

@keyframes tabAnim{
  0%{top:-100%;}
  100%{top:0;}
  }
.tab_wrap{width:500px; margin:80px auto;}
input[type="radio"]{display:none;}
.tab_area{font-size:0; margin:0 10px;}
.tab_area label{width:150px; margin:0 5px; display:inline-block; padding:12px 0; color:#999; background:#ddd; text-align:center; font-size:13px; cursor:pointer; transition:ease 0.2s opacity;}
.tab_area label:hover{opacity:0.5;}
.panel_area{overflow:hidden; height:210px; position:relative;}
.tab_panel{width:100%; background:#fff; overflow:hidden; position:absolute; height:100%;}
.tab_panel p{font-size:14px; letter-spacing:1px; text-align:center; padding:80px 0;}
#tab1:checked ~ .tab_area .tab1_label{background:#fff; color:#000;}
#tab1:checked ~ .panel_area #panel1{animation:tabAnim ease 0.4s forwards; -ms-animation:tabAnim ease 0.4s forwards; z-index:1;}
#tab2:checked ~ .tab_area .tab2_label{background:#fff; color:#000;}
#tab2:checked ~ .panel_area #panel2{animation:tabAnim ease 0.4s forwards; -ms-animation:tabAnim ease 0.4s forwards; z-index:1;}
#tab3:checked ~ .tab_area .tab3_label{background:#fff; color:#000;}
#tab3:checked ~ .panel_area #panel3{animation:tabAnim ease 0.4s forwards; -ms-animation:tabAnim ease 0.4s forwards; z-index:1;}

CSS、JSでの実装

tab1 tab2 tab3

panel3

panel2

panel1

JSで制御するCSSの記述

.tab_area label.active{background:#fff; color:#000;}
#cj_panelarea .tab_panel{transition:ease 0.4s;}
#cj_panelarea .tab_panel.active{animation:tabAnim ease 0.4s forwards; -ms-animation:tabAnim ease 0.4s forwards; z-index:1;}

JSの記述

$(".tab_label").on("click",function(){
  var $th = $(this).index()+1;
  $(".tab_label").removeClass("active");
  $(".tab_panel").removeClass("active");
  $(this).addClass("active");
  $("#panel"+$th).addClass("active").appendTo($("#cj_panelarea"));
});

Making the Selected Tab Float Like a Speech Bubble

CSSのみでの実装です

tab1 tab2 tab3

panel1

panel2

panel3

.tab_wrap{width:500px; margin:80px auto;}
.tab_area{font-size:0; margin:0 10px;}
.tab_area label{width:150px; margin:0 5px; display:inline-block; padding:12px 0; color:#999; background:#ddd; text-align:center; font-size:13px; cursor:pointer; transition:ease 0.2s; position:relative;}
.tab_area label:before{content:""; width:0; height:0; border:75px solid transparent; border-top:15px solid #ddd; display:block; position:absolute; left:0; right:0; bottom:0; margin:auto; transform:translateY(100%); transition:ease 0.2s;}
.tab_area label:hover{transform:translateY(-17px);}
.panel_area{width:100%; background:#fff; overflow:hidden; position:relative; z-index:0;}
.tab_panel{display:none;}
.tab_panel p{font-size:14px; letter-spacing:1px; text-align:center; padding:80px 0;}
#tab1:checked ~ .tab_area .tab1_label{background:#fff; color:#000; transform:translateY(-17px);}
#tab1:checked ~ .tab_area .tab1_label:before{border-top-color:#fff;}
#tab1:checked ~ .panel_area #panel1{display:block; animation:tabAnim ease 0.5s forwards; -ms-animation:tabAnim ease 0.5s forwards;}
#tab2:checked ~ .tab_area .tab2_label{background:#fff; color:#000; transform:translateY(-17px);}
#tab2:checked ~ .tab_area .tab2_label:before{border-top-color:#fff;}
#tab2:checked ~ .panel_area #panel2{display:block; animation:tabAnim ease 0.5s forwards; -ms-animation:tabAnim ease 0.5s forwards;}
#tab3:checked ~ .tab_area .tab3_label{background:#fff; color:#000; transform:translateY(-17px);}
#tab3:checked ~ .tab_area .tab3_label:before{border-top-color:#fff;}
#tab3:checked ~ .panel_area #panel3{display:block; animation:tabAnim ease 0.5s forwards; -ms-animation:tabAnim ease 0.5s forwards;}

Summary

What did you think?
This time, we focused on keeping the implementations simple, introducing relatively straightforward designs and animations.

Hopefully this article showed that convenient tab-switching functionality can be implemented quite easily.

CSS and JavaScript still offer many more properties and features,
so by making full use of them, you can create even richer and more user-friendly tab-switching content.

PREV
Vol.8510 Websites with Beautiful Anima…
NEXT
Vol.8710 Web design trend predictions …

MORE FOR YOU