この記事は2020年3月4日に書かれたもので、内容が古く現在では推奨されていない方法の可能性もありますのでご注意ください。
CSSとhtmlのradioボタンを使ってタブ切り替えを実装するサンプルを作ってみました。htmlの組み方にちょっと注意が必要ですが、動きはjavascriptで実装した場合と遜色ないと思うので、タブ切り替えの為だけにjavascript書きたくないという場合に便利です。
別記事のjQueryを使ってタブ切り替えを実装するサンプルと、ネイティブのJavaScript(脱jQuery)でタブ切り替えを実装するサンプルとの比較も兼ねて作ったので、htmlは似た構成にしています。
html
<input type="radio" name="tab" class="tab-radio" id="tab01" checked>
<input type="radio" name="tab" class="tab-radio" id="tab02">
<input type="radio" name="tab" class="tab-radio" id="tab03">
<ul class="tab-menu">
<li class="tab-menu__item"><label for="tab01" id="tabTrigger01" class="tab-trigger">タブ1</label></li>
<li class="tab-menu__item"><label for="tab02" id="tabTrigger02" class="tab-trigger">タブ2</label></li>
<li class="tab-menu__item"><label for="tab03" id="tabTrigger03" class="tab-trigger">タブ3</label></li>
</ul><!-- .tab-menu -->
<div class="tab-content">
<div class="tab-content__item" id="tabTarget01">
<p>タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。タブ1のコンテンツが入ります。</p>
</div><!-- .tab-content__item -->
<div class="tab-content__item" id="tabTarget02">
<p>タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。タブ2のコンテンツが入ります。</p>
</div><!-- .tab-content__item -->
<div class="tab-content__item" id="tabTarget03">
<p>タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。タブ3のコンテンツが入ります。</p>
</div><!-- .tab-content__item -->
</div><!-- .tab-content -->
タブ切り替えを実行するためのlabel(ここでは’.tab-trigger’)と切り替えを制御するためのinput type=”radio”(ここでは’.tab-radio’)、タブコンテンツ(ここでは’.tab-content__item’)の関係性が肝です。
CSSは親要素の指定ができません(Sassなどを使用すれば指定可能かと思いますが、CSSのみではできません。2020年2月現在)。
なので、切り替え制御のradioと切り替え実行のlabelの親要素(ここではul.tab-menu)、タブコンテンツ要素の親要素(ここではdiv.tab-content)が同列(兄弟関係)にないと動きません。
labelとそれぞれのinput type=”radio”をforで紐づけるのも忘れないようにします。
また、radioボタン(ここでは’.tab-radio’)、タブメニュー要素(ここでは’.tab-trigger’)、タブコンテンツ要素(ここでは’.tab-content__item’)にもそれぞれを特定するためにID属性をつけます。
最初から表示しておく要素には、それに対応したinput type=”radio”に’checked’属性をつけます。
CSS
.tab-radio { /* radio */
display: none;
}
/* タブメニュー */
.tab-menu {
display: flex;
margin: 0 -5px;
}
.tab-menu__item {
box-sizing: border-box;
padding: 0 5px;
}
.tab-trigger { /* label */
text-align: left;
cursor: pointer;
display: block;
padding: 10px;
border: 1px solid #ccc;
border-bottom: 0;
border-radius: 5px 5px 0 0;
overflow: hidden;
background-color: lightgray;
position: relative;
}
#tab01:checked ~ .tab-menu #tabTrigger01,
#tab02:checked ~ .tab-menu #tabTrigger02,
#tab03:checked ~ .tab-menu #tabTrigger03{
background-color: lightblue;
}
/* タブコンテンツ */
.tab-content {
border: 1px solid #ccc;
}
.tab-content__item {
box-sizing: border-box;
padding: 20px;
display: none;
text-align: left;
}
#tab01:checked ~ .tab-content #tabTarget01,
#tab02:checked ~ .tab-content #tabTarget02,
#tab03:checked ~ .tab-content #tabTarget03{
display: block;
animation: fade 0.5s ease;
}
@keyframes fade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
input type=”radio”(このソースだと’.tab-radio’)は見た目上は必要ないので、display: noneで非表示にします。
トリガーとなるlabel.tab-triggerはブロックにして、cursor: pointerを指定。
ターゲットになるタブコンテンツ本体の要素(’.tab-content__item’)は非表示を指定。
labelをクリックして、input type=”radio”がcheckedになったら、それに対応する兄弟要素に配置したタブメニューの親要素(’.tab-menu’)内のトリガー要素(タブメニュー)のID(ここでは’#tabTrigger01, #tabTrigger02, #tabTrigger03’)を兄弟要素指定({対象のinputのID}:checked ~ から始まる部分)してそれぞれがアクティブになったときのスタイルを指定します。
同じようにタブコンテンツの親要素(’.tab-content’)内のターゲット要素(タブコンテンツ本体)のID(ここでは’#tabTarget01, #tabTarget02, #tabTarget03’)にも表示用のスタイル(display: blockとアニメーション)を指定します。
表示制御のためにradioボタン、タブメニュー要素、タブコンテンツ要素のIDにスタイルを指定しないといけないのが少し手間なので、命名規則を予めナンバリングなどで決め、Sassのforで回して指定する方法がいいかと思います。
コメント
まだ、コメントはありません。