CSSのみでタブの切り替えを実装する - 実務で使えるのか検証する
今回はCSSのみでタブメニューの切り替えを実装する方法と実際の実務で使えるのか検証してみます。
前提条件は以下
- CSSのみで実装
- 1ページにタブメニューを複数設置しない
説明環境は以下
- macOS Monterey 12.5.1
- Visual Studio Code v1.73.1
この記事の目次
CSSのみでタブメニューを切り替える方法
タブメニューはJavaScriptを使用しなくてもCSSのみで実装できます。ただし、メリット デメリットがあるので正しく理解して実装しましょう。後ほど説明します。
HTMLで書くこと
<div class="p-tabs">
<input id="p-tabs__01" type="radio" name="p-tabs__tab" checked="">
<label class="p-tabs__tab" for="p-tabs__01">Human</label>
<input id="p-tabs__02" type="radio" name="p-tabs__tab">
<label class="p-tabs__tab" for="p-tabs__02">Gorilla</label>
<input id="p-tabs__03" type="radio" name="p-tabs__tab">
<label class="p-tabs__tab" for="p-tabs__03">Chimpanzee</label>
<div class="p-tabs__content p-tabs__content--01">A place where people live. The world. The world. The world in which people live and relate to each other. It is also a word that conceptually expresses the fragile and ephemeral state of such human society.</div>
<div class="p-tabs__content p-tabs__content--02">An ape living in Africa. They are very large and strong. They live in small families in tree nests.</div>
<div class="p-tabs__content p-tabs__content--03">An ape living in the forests of western and central Africa. They are about 150 cm long and black all over. They form groups, mainly consisting of males. They are cheerful, vocal, and intelligent.</div>
</div>
タブの部分はinputとlabel要素で構成されています。
ポイントは以下です。
- input要素のid名とlabel要素のfor属性を同じ名前にすること。
- タブとタブのコンテンツ部分のHTML階層を同じにする
CSSに書くこと
/*タブ全体のスタイル*/
.p-tabs {
max-width: 700px;
margin-left: auto;
margin-right: auto;
margin-top: 50px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
background-color: #fff;
}
/*タブのスタイル*/
.p-tabs__tab {
float: left;
display: flex;
justify-content: center;
align-items: center;
width: calc((100% - 6px) / 3);
height: 44px;
padding-bottom: 4px;
background-color: #eceff1;
font-size: 15px;
color: #78909c;
cursor: pointer;
font-weight: bold;
line-height: 1;
transition: color 0.2s, background-color 0.2s;
border-top: 4px solid transparent;
}
/*タブ同士の余白*/
.p-tabs__tab:not(:nth-of-type(1)) {
margin-left: 3px;
}
/*タブを非表示*/
input[name='p-tabs__tab'] {
display: none;
}
/*コンテンツ部分を非表示*/
.p-tabs__content {
display: none;
clear: both;
padding: 20px;
min-height: 200px;
background-color: #fff;
overflow: hidden;
}
/*タブにcheckedが入っているコンテンツ部分を表示*/
#p-tabs__01:checked ~ .p-tabs__content--01,
#p-tabs__02:checked ~ .p-tabs__content--02,
#p-tabs__03:checked ~ .p-tabs__content--03 {
display: block;
}
/*タブにcheckedが入っているタブのスタイル*/
.p-tabs input:checked + .p-tabs__tab {
background-color: #fff;
color: #0277bd;
border-top: 4px solid #0288d1;
}
CSSでタブコンテンツの表示切り替えは以下の部分で行なっています。
間接セレクタ(~の部分)を使ってinputにcheckedが入っているタブと、関連するタブコンテンツを紐づけています。
/*タブにcheckedが入っているコンテンツ部分を表示*/
#p-tabs__01:checked ~ .p-tabs__content--01,
#p-tabs__02:checked ~ .p-tabs__content--02,
#p-tabs__03:checked ~ .p-tabs__content--03 {
display: block;
}
タブ自体の切り替えは以下です。
inputにcheckedが入っている直下のlabel要素に対してスタイルを設定しています。
/*タブにcheckedが入っているタブのスタイル*/
.p-tabs input:checked + .p-tabs__tab {
background-color: #fff;
color: #0277bd;
border-top: 4px solid #0288d1;
}
CSSで実装するメリット デメリットとは?
タブの切り替えをCSSで行う場合のメリット デメリットについて考えてみました。
メリット
- JavaScriptを使用せず、HTMLとCSSのみで実装できるので手軽
デメリット
- HTML構造が決まっているため、複雑なデザインに対応できない
- 1ページ内に複数タブメニューを設置する場合はJavaScriptのほうが楽
- キーボード操作や文字の読み上げなどアクセシビリティに対応できない
メリットが手軽さだけに対して、デメリット割合が大きいように感じます。個人的にはたとえ手軽だとしても、柔軟性がなれればプロジェクトでは使いません。JavaScriptを使えば、このデメリットの部分はすべて対応できます。
JavaScriptでタブの切り替えを実装するには?
アクセシビリティに対応したタブメニューを実装するならMDN Web Docsにコードが載っているので参考にしてみてください。
タブメニューの読み上げ、キーボードでの操作が可能になります。
まとめ
今回はCSSのみでタブメニューの切り替えを実装する方法について説明しました。
手軽に実装できますが、デザインへの柔軟性やアクセシビリティの問題を考えると実務で使用するのは難しいかもしれません。