タブ切り替えは、必要な情報に迅速にアクセスするために役立ちます。
この記事では、HTMLとCSSだけでタブ切り替えを自作する方法を紹介します。通常はJavaScriptを使って実装されますが、HTMLとCSSだけでもシンプルなタブ切り替えが作れます。
この記事を読むと、機能的なタブ切り替えが実装できますのでぜひご覧ください。
タブ切り替えの動作イメージ
タブ切り替えでは、複数のタブボタンをクリックすることで異なるコンテンツを表示します。
初期状態ではタブ1が選択されているので(選択するタブは設定できます)、タブ2、タブ3をクリックしてみてください。クリックすることで下部に表示されるコンテンツが切り替わります。
See the Pen タブ切り替え(:has)基本 by はっちゃん (@hacchan) on CodePen.
この3タブの切り替えを作ります。
タブ切り替えを作るHTML
まず、基本的なHTMLの構造を見てみましょう。
<div class="tab-switch">
<label>
<input type="radio" name="TAB" checked>
タブ①
</label>
<div class="tab-content">
タブ①の内容をここに表示します
</div>
<label>
<input type="radio" name="TAB">
タブ②
</label>
<div class="tab-content">
タブ②の内容をここに表示します
</div>
<label>
<input type="radio" name="TAB">
タブ③
</label>
<div class="tab-content">
タブ③の内容をここに表示します
</div>
</div>
HTMLの解説
<div class="tab-switch">
はタブとコンテンツをまとめるコンテナです。
<div class="tab-switch">
</div>
<div class="tab-switch">
の中にコードが並ぶとなんだかよく分からないように見えますが、タブ1つのコードはこの部分です。
<label>
<input type="radio" name="TAB" checked>
タブ1
</label>
<div class="tab-content">
タブの内容をここに表示します
</div>
さらにイメージしやすいように、「タブボタンとなるHTML」と「タブが選択された際に表示するHTML」の2つに分けます。
タブボタンとなるHTML
<label>+<input>
がセット<label>
<input type="radio" name="TAB" checked>
タブ1
</label>
<label>
は各タブボタンとなる要素です。<label>
要素の中に<input type="radio">
が含まれ、ラジオボタンを利用してタブを切り替えます。<input type="radio">
とテキストで構成され、クリックするとラジオボタンの選択が切り替わります。
<input type="radio" name="TAB">
- ラジオボタンには
name="TAB"
を設定してグループ化しておくことで、複数のタブの中で1つのみが選択されるようにします。
- ラジオボタンには
- デフォルトで表示させたいタブには
checked
属性を付与して、初期表示の内容を指定します。
<input>
のtypeを”radio”にすることで、HTMLの「ラジオボタン」を活用してタブを作成します。
ラジオボタンの「同時にひとつのボタンしか選択できない」(ひとつのラジオボタンをチェックすると他のラジオボタンのチェックが自動的に外れる)性質を利用してタブ切り替えを作成します。この仕組みを利用することにより、Javascriptを使わないタブ切り替えが可能となります。
ラジオボタンは仕組みだけを利用するため非表示にします。
ちなみに、ラジオボタンを非表示にしないとこのようにダサイので注意…
タブが選択された際に表示するHTML
<div class="tab-content">
タブの内容をここに表示します
</div>
<div class="tab-content">
はタブごとに表示される内容です。- 選択されたタブに応じてこのコンテンツが切り替わるようにCSSで設定します。
HTML記述のポイント(抜粋)
記述する際のポイントとなる部分のみを抜粋します。
<input>
のname属性にすべて同じ名前を付ける。- タブ①
<input type="radio" name="TAB" checked>
- タブ②
<input type="radio" name="TAB">
- タブ③
<input type="radio" name="TAB">
- タブ①
- 初期状態でアクティブにするタブ
<input>
にcheckedを指定します
タブ切り替えを作るCSS
- レイアウト(見た目)を整える
- 選択されたタブの背景色と文字色を変更する
- コンテンツを一旦すべて非表示にする
- 選択されたタブのコンテンツを表示する
- ラジオボタンを非表示にする
コードの役割についてはざっくりと/*コメントアウト*/で記載しています。
/* タブ全体を囲むコンテナの設定 */
.tab-switch {
display: flex; /* タブを横並びに */
flex-wrap: wrap; /* 幅に応じて折り返し */
max-width: 800px; /* コンテナの最大幅を指定 */
margin: auto;/* コンテナの中央寄せ */
justify-content: center;/* タブの中央寄せ */
gap: 0 5px;/* タブ間の余白 */
}
/* 各タブボタンの設定 */
.tab-switch > label {
flex: 1 1 auto; /* タブが均等に幅をとるが、幅を超えると折り返す */
min-width: 70px; /* 各タブの最小幅を指定 */
order: -1; /* 上部に表示する */
position: relative; /* 絶対位置指定用の基準 */
padding: .7em 1em; /* 上下左右の内側余白 */
background-color: #f2f3f4; /* 背景色 */
color: #999; /* 文字色 */
text-align: center; /* 文字を中央揃え */
cursor: pointer; /* ポインターを指アイコンに変更 */
}
/* タブボタンのホバーおよび選択状態のスタイル */
.tab-switch > label:hover,
.tab-switch label:has(:checked) {
background-color: #757F96; /* ホバー/選択時の背景色 */
color: #fff; /* ホバー/選択時の文字色 */
}
/* ラジオボタン自体は非表示 */
.tab-switch input {
display: none; /* 見た目に表示されないようにする */
}
/* タブコンテンツのスタイル */
.tab-switch > div {
display: none; /* 初期状態では非表示 */
width: 100%; /* コンテンツ幅を全体に */
padding: 1.5em 1em; /* 内側余白 */
}
/* 選択されたタブのコンテンツを表示 */
.tab-switch label:has(:checked) + div {
display: block; /* 選択されたタブに対応するコンテンツを表示 */
}
CSSの解説
以下、特にポイントとなる部分をピックアップして解説します。
タブ全体を囲むコンテナの設定
/* タブ全体を囲むコンテナの設定 */
.tab-switch {
display: flex; /* タブを横並びに */
flex-wrap: wrap; /* 幅に応じて折り返し */
max-width: 800px; /* コンテナの最大幅を指定 */
margin: auto;/* コンテナの中央寄せ */
justify-content: center;/* タブの中央寄せ */
gap: 0 5px;/* タブ間の余白 */
}
display: flex;
コンテナ内の要素(各タブボタン)が横並びになるようにflex
レイアウトを使用しています。これにより、各タブが横一列に整列されます。flex-wrap: wrap;
ウィンドウ幅が小さくなった場合、タブが次の行に折り返されるように設定しています。max-width: 800px;
コンテナの最大幅を設定し、これ以上の幅にはならないよう制限しています。幅いっぱいにするときは100%にします。- 必要に応じて配置(中央寄せ)、タブ間の余白を調整します。
各タブボタンの設定
.tab-switch > label {
flex: 1 1 auto; /* タブが均等に幅をとるが、幅を超えると折り返す */
min-width: 70px; /* 各タブの最小幅を指定 */
order: -1; /* 上部に表示する */
position: relative; /* 絶対位置指定用の基準 */
padding: .7em 1em; /* 上下左右の内側余白 */
background-color: #f2f3f4; /* 背景色 */
color: #999; /* 文字色 */
text-align: center; /* 文字を中央揃え */
cursor: pointer; /* ポインターを指アイコンに変更 */
}
flex: 1 1 auto;
タブが均等に幅を取るが、幅が限界に達した場合に折り返す設定です。min-width
を設定することで、各タブの最小幅を確保しつつ、限界まで幅が狭まったときに折り返すように調整しています。order: -1;
タブボタンを上部に配置するために使用しています。この設定により、他の要素よりも優先的に表示されます。
タブボタンのホバーおよび選択状態のスタイル
.tab-switch > label:hover,
.tab-switch label:has(:checked) {
background-color: #757F96; /* ホバー/選択時の背景色 */
color: #fff; /* ホバー/選択時の文字色 */
}
label:has(:checked)
選択状態のタブボタンを視覚的に分かりやすく表示するためのスタイルです。選択されると背景色が変わります。
ラジオボタンを非表示にする
.tab-switch input {
display: none; /* 見た目に表示されないようにする */
}
ラジオボタンは仕組みだけ利用するためボタン自体は非表示にしています。実際はlabel
クリックでタブ切り替えを実現しています。
タブコンテンツのスタイル
.tab-switch > div {
display: none; /* 初期状態では非表示 */
width: 100%; /* コンテンツ幅を全体に */
padding: 1.5em 1em; /* 内側余白 */
}
display: none;
初期状態ではすべてのタブコンテンツが非表示です。どのタブも選択されていない状態では、表示されません。
選択されたタブのコンテンツを表示
.tab-switch label:has(:checked) + div {
display: block; /* 選択されたタブに対応するコンテンツを表示 */
}
label:has(:checked) + div
選択状態のラジオボタンに関連するコンテンツのみを表示するためのセレクタです。選択されたタブのlabel
に隣接するdiv
(つまり対応するタブコンテンツ)が表示されるようになります。display: block;
選択されたタブのコンテンツだけがblock
で表示され、他のコンテンツは非表示のままです。
タブのデザイン
CSSを少し変更することで、お好みのデザインに変更できます。
シンプルなタブ
シンプルな配色とスタイルでまとめたタブデザインです。
See the Pen 予備 by はっちゃん (@hacchan) on CodePen.
丸みをつけたタブ
タブを丸くしたデザインです。
See the Pen tab-tab(吹き出し) by はっちゃん (@hacchan) on CodePen.
吹き出し
吹き出しのようなデザインにすることもできます。
See the Pen タブ切り替え(:has)吹き出し by はっちゃん (@hacchan) on CodePen.
タブ数の増減について
タブひとつ分のHTMLはこの部分、タブと表示する内容で一セットです。
<label>
<input type="radio" name="TAB" checked>
タブ1
</label>
<div class="tab-content">
タブの内容をここに表示します
</div>
タブを増やす場合
HTMLで<label>
と<div class="tab-content">
のセットを追加し、CSSの調整は不要です。
タブを減らす場合
同様に、HTMLで<label>
と<div class="tab-content">
のセットを削除するだけで完了します。
タブ切り替えをHTMLとCSSで実装した際の問題
ワードプレス(特にクラシックエディタ)を使用してHTMLを記述すると、意図せず<p>
タグが自動挿入されることがあります。この仕様は通常、文章の整形や段落分けを助けるために便利ですが、タブ切り替えのようなカスタムHTML構造には影響を与える場合があります。以下に、具体的な問題点と対応策を解説します。
問題点:自動挿入される <p>
タグ
タブ切り替えのHTML構造では、<input>
や<label>
タグ、<div>
などを正確に配置する必要がありますが、ワードプレスが自動で<p>
を挿入することで以下の問題が発生します。
- HTML構造の崩れ
自動的に挿入された<p>
が、要素間に余分な空白や高さを作り、デザインが崩れることがあります。 - CSSの適用に問題
期待している子要素にスタイルが適用されず、意図したデザインや動作が機能しない場合があります。
解決策
「カスタムHTML」で編集し、改行を避ける
ブロックエディタでHTMLを記述する際に「カスタムHTML」を使用します。
- 「カスタムHTML」では、HTMLタグをそのまま記述可能で
<p>
タグの自動挿入が抑制されます。 - タブ切り替えのHTMLを1行にまとめることでワードプレスが不要な改行を認識しなくなります。
<div class="tab-switch"><label> <input type="radio" name="TAB" checked> タブ①</label>
プラグインを使う
プラグインを使う方法もあります。
実際に当記事の方法でpタグが自動挿入される事例があり、対策された方のコメントを掲載しますので参考にしてください。
「Toggle wpautop」:ワードプレスの自動整形機能をページ毎に無効化できるプラグインです。
ですが、2024年11月現在このプラグインは4年間更新されていません。メンテナンスやサポートがされていないかもしれず、最新バージョンのワードプレスで使用した場合は互換性に不具合が起こる可能性があります。
他にはPHPコードで自動整形を無効化する方法もありますが、全ページで<p>
の自動挿入が無効化される等の影響が考えられるため、確実に改行を避ける方法で対策をおこなってください。
まとめ
HTMLとCSSのみで、シンプルで機能的なタブ切り替えを作成することができました。ラジオボタンとlabel
を活用することで、JavaScriptなしで柔軟なタブ切り替えが実現可能です。
当サイトで紹介しているワードプレステーマ「Cocoon」でのサイト型トップページの作り方に、このタブ切り替えを導入しています。
この記事は以上です。
Comment コメントはこちらへ
返信ありがとうございます。
Cocoonではないのでショートコードは使えないのですが、記事拝見させて頂きました。
色々と試みてみたのですが、結局、素人にはどの要素をいれるとカテゴリーの記事一覧が表示されるのかわからずでした…
もう少し頑張ってみます。
コメント失礼します。
HTMLにある「コンテンツをここに入れる」には何を入れたら良いのでしょうか?
タブ自体は奇麗に表示されていますが、各タブの下にカテゴリーを表示したいのですが、URLなどを入力するようなものではないようですし…
他のサイトも拝見したのですが、ここに何を入れるとカテゴリーや記事が表示されるのかわからず質問させて頂きました。
新着記事や人気記事を表示したいならこちらの記事に書いたショートコード(Cocoon独自のものです)を使いますが、
カテゴリーを表示したいということであれば、トップページの作り方という記事を更新しましたのでこちらが参考になるかと思います^^
https://turicco.com/2022/10/05/cocoon-toppage/#toc14