CSSだけでタブの切替を実装する方法のメモ
#基本仕様
CSSのみでタブの切替を実装する方法は3種類あります。
- target属性を使う
- フラグメント識別子を使う
- inputタグを使う
いろいろやり方はありますが、target属性やフラグメント識別子を使うとページ遷移が発生してしまい、前のページに戻るのがめんどくさくなってしまうので個人的に好きじゃないです。
なので今回はinputタグを使って実装します。
#HTML
inputタグとlabelタグを使ってタブを作ります。
input
のidとlabel
のfor属性が対応しており、label
をクリックするとそれに対応したinput
にchecked属性がつきます。
inputのchecked属性で要素の表示/非表示を切り替えます。
<!-- TAB CONTROLLERS -->
<input id="panel-1-ctrl" class="panel-radios" type="radio" name="tab-radios" checked>
<input id="panel-2-ctrl" class="panel-radios" type="radio" name="tab-radios">
<input id="panel-3-ctrl" class="panel-radios" type="radio" name="tab-radios">
<!-- TABS LIST -->
<ul id="tabs-list">
<!-- MENU TOGGLE -->
<li id="li-for-panel-1">
<label class="panel-label" for="panel-1-ctrl">Tab1</label>
</li>
<li id="li-for-panel-2">
<label class="panel-label" for="panel-2-ctrl">Tab2</label>
</li>
<li id="li-for-panel-3">
<label class="panel-label" for="panel-3-ctrl">Tab3</label>
</li>
</ul>
<!-- THE PANELS -->
<article id="panels">
<div class="container">
<section id="panel-1">
<main>
<p>Content1</p>
</main>
</section>
<section id="panel-2">
<main>
<p>Content2</p>
</main>
</section>
<section id="panel-3">
<main>
<p>Content3</p>
</main>
</section>
</div>
</article>
#CSS
##擬似クラス:checked
今回は**擬似クラス:checked
**を使用してタブの切替を行います。
擬似クラス:checked
はチェックされているラジオボタン(<input type="radio">
)、チェックボックス(<input type="checkbox">
)、オプションボタン(<select>
内にある <option>
)に適用されます。
基本構文
"inputタグの「id」または「class」":checked ~ "CSSを適用したい要素" {};
詳しくはこちら
##切り替え実装
今回は下記のようにしてタブの表示/非表示を切り替えています。
#panels section main {
max-height: 0;
/*以下省略*/
}
#panel-1-ctrl:checked ~ #panels #panel-1 main {
max-height: initial;
opacity: 1;
padding: 48px 24px;
}
初期値ではmax-height: 0
が設定され非表示になっていますが、#panel-1-ctrl
がcheckedになると下のCSSが適用され、要素が出現します。
今回はアニメーション実現のためmax-height: 0
を使用していますが、display: none
でも大丈夫です。
###CSS全文
label.panel-label {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
display: block;
width: 100%;
color: #bdc3c7;
cursor: pointer;
background-color: #ecf0f1;
-webkit-transition-property: background-color, color;
transition-property: background-color, color;
-webkit-transition-duration: 200ms;
transition-duration: 200ms;
}
label.panel-label:hover {
color: #003399;
}
#panels {
background-color: white;
}
#panels .container {
margin: 0 auto;
width: 90%;
}
#panels section header label.panel-label {
padding: 12px 24px;
box-sizing: border-box;
}
#panels section main {
box-sizing: border-box;
max-height: 0;
opacity: 0;
-webkit-transition: opacity 600ms;
transition: opacity 600ms;
overflow-y: hidden;
}
#panel-1-ctrl:checked ~ #panels #panel-1 main {
max-height: initial;
opacity: 1;
padding: 48px 24px;
}
#panel-2-ctrl:checked ~ #panels #panel-2 main {
max-height: initial;
opacity: 1;
padding: 48px 24px;
}
#panel-3-ctrl:checked ~ #panels #panel-3 main {
max-height: initial;
opacity: 1;
padding: 48px 24px;
}
#panel-1-ctrl:checked ~ #tabs-list #li-for-panel-1 {
pointer-events: none;
cursor: default;
-webkit-transform: translate3d(0, 1px, 0);
transform: translate3d(0, 1px, 0);
box-shadow: none;
border-right: none;
}
#panel-1-ctrl:checked ~ #tabs-list #li-for-panel-1.last {
border-right: 1px solid transparent;
}
#panel-1-ctrl:checked ~ #tabs-list #li-for-panel-1 + li {
border-left: 1px solid #dfdfdf;
}
#panel-1-ctrl:checked ~ #tabs-list #li-for-panel-1 label.panel-label {
background-color: white;
color: #003399;
padding-top: 24px;
}
#panel-1-ctrl:checked ~ #tabs-list #li-for-panel-1 label.panel-label::after {
height: 6px;
}
#panel-2-ctrl:checked ~ #tabs-list #li-for-panel-2 {
pointer-events: none;
cursor: default;
-webkit-transform: translate3d(0, 1px, 0);
transform: translate3d(0, 1px, 0);
box-shadow: none;
border-right: none;
}
#panel-2-ctrl:checked ~ #tabs-list #li-for-panel-2.last {
border-right: 1px solid transparent;
}
#panel-2-ctrl:checked ~ #tabs-list #li-for-panel-2 + li {
border-left: 1px solid #dfdfdf;
}
#panel-2-ctrl:checked ~ #tabs-list #li-for-panel-2 label.panel-label {
background-color: white;
color: #003399;
padding-top: 24px;
}
#panel-2-ctrl:checked ~ #tabs-list #li-for-panel-2 label.panel-label::after {
height: 6px;
}
#panel-3-ctrl:checked ~ #tabs-list #li-for-panel-3 {
pointer-events: none;
cursor: default;
-webkit-transform: translate3d(0, 1px, 0);
transform: translate3d(0, 1px, 0);
box-shadow: none;
border-right: none;
}
#panel-3-ctrl:checked ~ #tabs-list #li-for-panel-3.last {
border-right: 1px solid transparent;
}
#panel-3-ctrl:checked ~ #tabs-list #li-for-panel-3 + li {
border-left: 1px solid #dfdfdf;
}
#panel-3-ctrl:checked ~ #tabs-list #li-for-panel-3 label.panel-label {
background-color: white;
color: #003399;
padding-top: 24px;
}
#panel-3-ctrl:checked ~ #tabs-list #li-for-panel-3 label.panel-label::after {
height: 6px;
}
ul#tabs-list {
display: flex;
justify-content: center;
list-style: none;
text-align: center;
border-bottom: 1px solid #dfdfdf;
margin: 0;
padding: 0;
text-align: center;
border-bottom: 1px solid #dfdfdf;
}
ul#tabs-list li {
display: flex;
text-align: center;
font-size: 0.875em;
width: 18%;
box-shadow: 0px -2px 2px rgba(0, 0, 0, 0.05);
border-right: 1px solid #dfdfdf;
position: relative;
}
ul#tabs-list li:hover {
-webkit-transition: none;
transition: none;
border-right: none;
}
ul#tabs-list li:hover.last {
border-right: 1px solid transparent;
}
ul#tabs-list li:hover + li {
border-left: 1px solid #dfdfdf;
}
ul#tabs-list li label.panel-label {
position: relative;
padding: 24px 0;
font-size: 0.875em;
}
ul#tabs-list li label.panel-label::after {
content: "";
position: absolute;
width: 100%;
left: 0;
bottom: 100%;
background-color: #003399;
height: 0;
-webkit-transition-property: height;
transition-property: height;
-webkit-transition-duration: 200ms;
transition-duration: 200ms;
}
ul#tabs-list li label.panel-label:hover {
padding-top: 24px;
}
ul#tabs-list li label.panel-label:hover::after {
height: 6px;
}
main {
width: 70%;
margin: 0 auto;
}
.panel-radios {
display: none;
}
body {
background: #00bfff;
color: #444444;
font-family: "Open Sans", "Helvetica Neue", Helvetica, sans-serif;
}
main p {
line-height: 1.8;
}