必要な情報へ迅速にアクセスするために便利なのが「タブ切り替え」機能。
この記事では、JavaScriptを使わずにHTMLとCSSだけでタブ切り替えを実現する方法をご紹介します。フォーム要素であるラジオボタンを応用することで、軽量かつシンプルに実装可能です。
- 実装例:当サイトトップページ
- 「新着記事」と「更新記事」の切り替えに使用しています。
この記事を読むと、機能的なタブ切り替えが実装できますのでぜひご覧ください。
タブ切り替えの動作イメージ
タブ切り替えでは、複数のタブボタンをクリックすることで異なるコンテンツを表示します。
初期状態ではタブ1が選択されているので(選択するタブは設定できます)、タブ2、タブ3をクリックしてみてください。クリックすることで下部に表示されるコンテンツが切り替わります。
See the Pen タブ切り替え(:has)基本 by はるみ (@hacchan) on CodePen.
この3タブの切り替えを作ります。
タブ切り替えを作る基本のHTML構造

以下が基本的なタブ切り替えのHTML構造です。<label>
と <input type="radio">
をセットにして、タブ切り替えを制御しています。
<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>
各構成要素の解説
<input type="radio">
で「どのタブが選ばれているか」を管理
HTMLの<input>
タグは、ユーザーが情報を入力したり選択したりするためのフォーム部品です。その中でtype="radio"
は、「ラジオボタン」と呼ばれる選択肢の中から1つだけを選べるボタンを作成します。
<input id="tab1" type="radio" name="TAB" checked>
type="radio"
- ラジオボタンとして機能させます。タブ切り替えでは「現在どのタブが選ばれているか」を判断する仕組みに使われます。
name="TAB"
- 複数のラジオボタンを「同じグループ」としてまとめる役割。これが同じ名前で統一されていれば、1つを選択すると他の選択は自動的に解除されます。
id="tab1"
- このラジオボタンの識別子。後述の
<label>
タグと紐づけて、「ラベルをクリックするとこのボタンが選ばれる」ようにします。
- このラジオボタンの識別子。後述の
checked
- 初期表示でこのラジオボタンが選ばれた状態にします。つまり「ページを開いたときに表示しておきたいタブ」に付ける属性です。
<label>
はタブの「ボタン」として機能する
ラジオボタンそのもの(<input>
)は非表示にするため、見た目としての「タブボタン」は<label>
タグを使って作ります。
<label for="tab1">タブ①</label>
for
属性について
for="tab1"
は、同じID(ここではid="tab1"
)を持つ<input>
とセットで使います。- ラベル部分(タブ①)をクリックすると、対応するラジオボタンが選択されるようになります。
この仕組みにより、CSSで見た目をボタン風にスタイリングすることが可能です。実際のクリックイベントはラジオボタンの選択として扱われるので、JavaScriptを使わなくてもタブの切り替えが実現できます。
別パターン:ラベルの中に <input>
を内包する書き方(よりシンプル)
<label>
<input type="radio" name="TAB" checked>
タブ①
</label>
この書き方では for
属性や id
属性を使わず、ラベルの中にラジオボタンを内包しています。HTMLがスッキリするため、簡易的に使いたい場合はこちらのパターンもおすすめです。
デザイン面の注意点
この構成では、ラジオボタンの見た目(ポチッとする丸ボタン)はあくまで内部的な仕組みとして使うもので、画面上には見せないようにするのが一般的です。
もしラジオボタンをそのまま表示してしまうと、以下のように見栄えが悪くなるため注意。
<div class="tab-content">
に各タブの内容を記述
実際にタブを切り替えたときに表示される中身(コンテンツ部分)は、<div class="tab-content">
タグ内に記述します。
<div class="tab-content">
タブ①の内容をここに表示します
</div>
<div>
タグは汎用のコンテナ(囲い)タグ。ここにタブごとの内容を入れます。- この
tab-content
クラスを持つコンテンツを、CSSのスタイルルールで「表示する」「隠す」制御を行います。 - ユーザーがタブをクリックしてラジオボタンが切り替わると、それに対応する
tab-content
だけが表示され、他のタブの内容は非表示になります。
HTML記述のポイント(抜粋)
記述する際のポイントとなる部分のみを抜粋します。
<input>
のname属性にすべて同じ名前を付ける。
- タブ①
<input type="radio" name="TAB" checked>
- タブ②
<input type="radio" name="TAB">
- タブ③
<input type="radio" name="TAB">
- タブ①
タブ切り替えを実現するCSSの書き方(ラジオボタン+ラベル+CSSのみ)

JavaScriptを使わずにCSSのみで実装できる「タブ切り替え」のCSSコードと、その役割についてわかりやすく解説します。
下記がタブ切り替えに使うCSSコードです。label:has(:checked)
セレクタを活用して、選択されたタブの内容だけを表示する仕組みです。コードには簡単なコメントも添えています。
/* タブ全体を囲むコンテナの設定 */
.tab-switch {
display: flex; /* タブを横並びに */
flex-wrap: wrap; /* 幅に応じて折り返し */
margin: auto; /* コンテナの中央寄せ */
justify-content: center; /* タブの中央寄せ */
gap: 0 5px; /* タブ間の余白 */
}
/* 各タブボタンの設定 */
.tab-switch > label {
flex: 1 1 auto; /* タブが均等に幅をとるが、幅を超えると折り返す */
order: -1; /* 上部に表示する */
position: relative; /* 絶対位置指定用の基準 */
padding: 0.7em 1em; /* 上下左右の内側余白 */
background-color: #f2f3f4; /* 背景色 */
color: #999; /* 文字色 */
text-align: center; /* 文字を中央揃え */
cursor: pointer; /* ポインターを指アイコンに変更 */
transition: 0.3s all; /* 変化を滑らかに */
}
/* タブボタンのホバーおよび選択状態のスタイル */
.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; /* 選択されたタブに対応するコンテンツを表示 */
}
各スタイルの解説
.tab-switch
:タブ全体のレイアウトを整える
タブボタンとコンテンツを囲むコンテナのスタイルです。display: flex
でタブボタンを横並びにし、画面幅に応じて折り返せるよう flex-wrap: wrap
を設定。中央寄せやタブ間の余白もここで調整します。
.tab-switch > label
:タブボタンのデザイン
ラジオボタンと対応する label
をタブボタンとして使用します。
flex: 1 1 auto
で、幅が自動的に調整され、必要に応じて折り返します。order: -1
により、コンテンツより上にタブボタンが表示されます。cursor: pointer
でボタンらしい見た目に。
.tab-switch > label:hover, label:has(:checked)
:選択中・ホバー中のスタイル
label:hover
でマウスオーバー時のスタイルを、label:has(:checked)
で現在選択されているタブボタンのスタイルを指定しています。
.tab-switch input
:ラジオボタンの非表示
タブの切り替えはラジオボタンの仕組みで実現していますが、見た目には表示しないよう display: none;
にしています。label
をクリックすることで、対応するラジオボタンが選択されます。
.tab-switch > div
:タブコンテンツの表示/非表示
タブの中身となるコンテンツ部分は、デフォルトで display: none
にして非表示にします。
.tab-switch label:has(:checked) + div
:選択されたコンテンツを表示
ラジオボタンがチェックされた状態の label
に隣接する div
のみを display: block
にして表示します。この仕組みにより、1つのタブを選ぶと対応する内容だけが表示され、他の内容は非表示のままになります。
タブのデザイン
CSSを調整するとお好みのデザインに変更できます。HTML、CSSは下記CodePenを参照ください。
シンプルなタブ
シンプルな配色とスタイルでまとめたタブデザインです。
See the Pen 予備 by はるみ (@hacchan) on CodePen.
丸みをつけたタブ
タブを丸くしたデザインです。
See the Pen tab-tab(吹き出し) by はるみ (@hacchan) on CodePen.
吹き出し
吹き出しのようなデザインにすることもできます。
See the Pen タブ切り替え(:has)吹き出し by はるみ (@hacchan) on CodePen.
タブ数の増減について
タブ1つ分のHTMLは、以下のように<label>
と<div class="tab-content">
のセットで構成されています。
<label><input type="radio" name="TAB" checked>タブ1</label>
<div class="tab-content">
タブの内容をここに表示します
</div>
タブを増やす場合
タブを追加するには、上記のセット(<label>
と <div class="tab-content">
)をHTMLに追加するだけでOKです。CSSの追加・変更は必要ありません。
タブを減らす場合
タブを減らすときも、該当する <label>
と <div class="tab-content">
をHTMLから削除するだけで対応可能です。
タブ切り替えをHTMLとCSSで実装した際の問題点
WordPress(特にクラシックエディタ)では、HTMLに意図せず <p>
タグが自動挿入されることがあります。
この仕様は本来、段落を整形するための便利な機能ですが、タブ切り替えなどのカスタムHTML構造では問題を引き起こす場合があります。
よくある問題
- HTML構造の崩れ
自動挿入された<p>
タグが要素の間に余分な余白や高さを作り、デザインが崩れることがあります。 - CSSの適用に不具合
<p>
タグが間に入ることで、意図した子要素にスタイルが適用されず動作しなくなるケースがあります。
解決策
「カスタムHTML」で編集し、改行を避ける
ブロックエディタを使用している場合は、「カスタムHTML」ブロックを使ってコードを記述しましょう。
- HTMLタグをそのまま書けるため、WordPressの自動整形(
<p>
挿入)を回避できます。 - HTML構造を1行にまとめることで、改行が認識されず余分なタグの挿入を防げます。
<div class="tab-switch"><label> <input type="radio" name="TAB" checked> タブ①</label>
プラグインを使う
自動挿入される <p>
タグを抑制できるプラグインの利用も一つの方法です。
使用例「Toggle wpautop」
- 固定ページや投稿ごとに
<p>
タグの削除が可能。 - テーマ全体ではなく、対象ページのみ制御できるのが利点です。
実際の使用例:
「フロントページの p
タグ変換を無効化したところ、タブ切り替えが正常に動作しました。」
注意点
- 「Toggle wpautop」は2024年11月時点で4年間更新されておらず、最新のWordPressとの互換性に不安があります。
- 導入には注意が必要です。特に本番環境では、事前にテストすることをおすすめします。
「Cocoon」テーマで利用できる便利な「タブ」ブロック
WordPressテーマ「Cocoon」では、Cocoon 2.7.3~直感的にタブ切り替えができる便利な「タブ」ブロックが追加されました。この機能を利用すればHTMLコードを書くことなくタブ切り替えを実装できます。
- 直感的な操作:ブロック内でタブの内容を編集可能。
- レスポンシブ対応:スマートフォンやタブレットでも使いやすいレイアウト。
さらに、当サイトでは「Cocoon」のタブのスタイルを簡単に切り替えるカスタマイズを紹介しています。「Cocoon」のタブブロックを活用してサイトのデザインを一段と引き立てましょう。
まとめ
HTMLとCSSのみで、シンプルで機能的なタブ切り替えを作成することができました。ラジオボタンとlabel
を活用することで、JavaScriptなしで柔軟なタブ切り替えが実現可能です。
当サイトでは、WordPressテーマ「Cocoon」を使用したサイト型トップページにこのタブ切り替え機能を導入しています。詳細は以下の記事からご確認ください。
Cocoonで作るサイト型トップページ/SWELL風デザインを見る
この記事は以上です。
Comment コメントはこちらへお願いします
返信ありがとうございます。
Cocoonではないのでショートコードは使えないのですが、記事拝見させて頂きました。
色々と試みてみたのですが、結局、素人にはどの要素をいれるとカテゴリーの記事一覧が表示されるのかわからずでした…
もう少し頑張ってみます。
コメント失礼します。
HTMLにある「コンテンツをここに入れる」には何を入れたら良いのでしょうか?
タブ自体は奇麗に表示されていますが、各タブの下にカテゴリーを表示したいのですが、URLなどを入力するようなものではないようですし…
他のサイトも拝見したのですが、ここに何を入れるとカテゴリーや記事が表示されるのかわからず質問させて頂きました。
新着記事や人気記事を表示したいならこちらの記事に書いたショートコード(Cocoon独自のものです)を使いますが、
カテゴリーを表示したいということであれば、トップページの作り方という記事を更新しましたのでこちらが参考になるかと思います^^