タブメニューをCSSだけで作る方法
はじめに
以前コーディングを担当した案件でCSSでタブメニューを作ったことがあります。
しかし最近はタブメニューを作る機会が無く、このまま時間が経つと作り方を忘れてしまいそうだったので自分のために作り方をまとめました。
仕上がりイメージ
目次
タブメニューの仕組みと制作の流れ
CSSで作るタブメニューの仕組みは以下のとおりです。
- タブ(
label
)をクリックする - タブに連動したラジオボタンにチェックが入る
- チェックが入ったラジオボタンに連動したコンテンツが表示される
- それ以外のコンテンツは非表示
制作の流れは以下のような感じになります。
- ラジオボタン
<input type="radio">
をタブの数だけ作る - タブ(
label
)を必要な数だけ作る - コンテンツをタブと同じ数だけ作る
- タブをクリックするとラジオボタンにチェックが入るようHTMLを設定する
- チェックが入ったタブのコンテンツのみ表示するよう、CSSを設定する
説明するより実際にソースを見て頂いた方が分かりやすいと思いますので以下のソースをご確認下さい。
HTML
- <input id="radio01" type="radio" class="p-radio" name="tabmenu" checked>
- <input id="radio02" type="radio" class="p-radio" name="tabmenu">
- <div class="p-tabmenu_head">
- <label for="radio01" class="p-tab_btn01">ボタン1</label>
- <label for="radio02" class="p-tab_btn02">ボタン2</label>
- </div>
- <div class="p-tabmenu_body">
- <div class="p-tab_cont01">
- <p>1つめのコンテンツ</p>
- </div>
- <div class="p-tab_cont02">
- <p>2つめのコンテンツ</p>
- </div>
- </div>
次にもう少し細かく分割して説明します。
タブ部分を作る
上記HTMLのボタン部分にフォーカスして見て下さい。
ソースをなるべくシンプルに見せたいので、いったんClassを外してみます。
HTML(Classを削除)
- <input id="radio01" type="radio" name="tabmenu" checked>
- <input id="radio02" type="radio" name="tabmenu">
- <div>
- <label for="radio01">ボタン1</label>
- <label for="radio02">ボタン2</label>
- </div>
それぞれのラジオボタンにid
を設定し、<label for="radio0*">
でlabel
をクリックすると連動したid
にチェックが入るようにします。
id="radio01"
のラジオボタンにchecked
を設定し、初期でコンテンツが表示されるようにします。
できあがったもの
CSSで装飾していないのでデザイン的に少し分かりにくいですが、「ボタン1」「ボタン2」をクリックすると、それと連動したラジオボタンにチェックが入ります。
次に、ボタンをクリックすると連動するコンテンツが表示されるようにします。
タブメニューとコンテンツの表示・非表示を調整する
最初に記述したHTMLを改めて記述しておきます。
HTML
- <input id="radio01" type="radio" class="p-radio" name="tabmenu" checked>
- <input id="radio02" type="radio" class="p-radio" name="tabmenu">
- <div class="p-tabmenu_head">
- <label for="radio01" class="p-tab_btn01">ボタン1</label>
- <label for="radio02" class="p-tab_btn02">ボタン2</label>
- </div>
- <div class="p-tabmenu_body">
- <div class="p-tab_cont01">
- <p>1つめのコンテンツ</p>
- </div>
- <div class="p-tab_cont02">
- <p>2つめのコンテンツ</p>
- </div>
- </div>
上記HTMLをもとに、改めて行いたい処理は以下のとおりです。
id="radio01"
のラジオボタンにチェックが入ったらp-tab_cont01
を表示させるid="radio02"
のラジオボタンにチェックが入ったらp-tab_cont02
を表示させる- チェックが入っていないコンテンツは非表示にする
これを実現させるには、CSSを以下のように設定します。
CSS
- /*初期段階ではチェックが入っていないコンテンツは非表示*/
- .p-tab_cont01,
- .p-tab_cont02 {
- display: none;
- }
- /*チェックが入っているIDに連動したコンテンツを表示する*/
- #radio11:checked ~ .p-tabmenu_body .p-tab_cont01,
- #radio12:checked ~ .p-tabmenu_body .p-tab_cont02 {
- display: block;
- }
- /*チェックが入っているボタンの色を変更する*/
- #radio11:checked ~ .p-tabmenu_head .p-tab_btn01,
- #radio12:checked ~ .p-tabmenu_head .p-tab_btn02 {
- background: #333;
- color: #fff;
- }
こんな感じです。
上記のCSSだけを設定すると以下のようになります。
できあがったもの
これで、チェックが入ったラジオボタンに連動したコンテンツのみが表示されるようになりました。
あとはCSSで全体を整えれば完成です。
CSSで全体を整える
以下のようにCSSを設定しました。
CSS
- /*ラジオボタンは非表示にする*/
- .p-radio {
- display: none;
- }
- /*タブメニュー全体の配置*/
- .p-tabmenu_head {
- display: flex;
- align-items: stretch;
- justify-content: center;
- gap: 1rem;
- }
- /*タブメニューのボタンの装飾*/
- .p-tabmenu_head .p-tab_btn01,
- .p-tabmenu_head .p-tab_btn02 {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 200px;
- height: 40px;
- color: #444;
- background: #ddd;
- cursor: pointer; /*デフォルトではマウスオーバーでマウス表示が切り替わらない*/
- user-select: none;
- }
- /*コンテンツ部分の大枠の設定*/
- .p-tabmenu_body {
- border: 4px solid #ccc;
- padding: 20px;
- box-sizing:border-box;
- }
- /*チェックが入っていないコンテンツは非表示*/
- .p-tab_cont11,
- .p-tab_cont12 {
- display: none;
- }
- /*チェックが入っているIDに連動したコンテンツを表示する*/
- #radio11:checked ~ .p-tabmenu_body .p-tab_cont01,
- #radio12:checked ~ .p-tabmenu_body .p-tab_cont02 {
- display: block;
- }
- /*チェックが入っているボタンの色を変更する*/
- #radio11:checked ~ .p-tabmenu_head .p-tab_btn01,
- #radio12:checked ~ .p-tabmenu_head .p-tab_btn02 {
- background: #333;
- color: #fff;
- }
上記設定をしたタブメニューが以下のとおりです。
できあがったもの
注意点
注意点といいますか、私が初めてタブメニューを作った時、どうしてもボタンと表示の連動が上手くいかなくて苦労しました。
試行錯誤して分かったのですが、CSSにある~
(一般兄弟結合子)がクセ者で、これがあると兄弟要素内(同じディレクトリ)の要素でないとCSSが適用されません。
「じゃあ一般兄弟結合子を外したら良いじゃない」と思いますが、これを外すと関係のないタブメニューが誤作動してしまうのではないかと思います(試してないけど)。
自分なりにアレンジしたらタブメニューの実装ができなくなった場合は、input
等のディレクトリを調整すると上手くいくかもしれません。