サイト型トップページの作り方を公開しています!
Webカスタマイズ

タブ切り替えをHTMLとCSSで実装(JavaScriptなし)

アイキャッチ|タブ切り替え
記事内に広告が含まれています

「タブ切り替えを作りたいけど、JavaScriptを書くのはちょっと大げさかも…」

そんなときは、HTMLとCSSだけでもタブ切り替えを実装できます。

この記事では、ブラウザ対応の広い「:checked版」と、コードをスッキリ書ける「:has()版」の2つの方法を紹介します。

どちらもコピペで試せるサンプル付き。さらに、均等幅・吹き出し風・丸ボタン風などのカスタマイズ例や、WordPressで実装するときの注意点もまとめました。

まずは動くコードを試しながら、自分のサイトに合ったタブ切り替えを作ってみましょう。

スポンサーリンク

HTMLとCSSだけで実現!タブ切り替えの実装方法

ここでは次の2つの方法を紹介します。

  1. :checked版 → ブラウザ対応が広く、実用向き
  2. :has版 → モダンな書き方でスッキリ
項目:checked版:has版
書き方input → label → content の順が必須構造の自由度が高い
コード量少し長いスッキリ
ブラウザ対応広い(古い環境でもOK)モダンブラウザ
実用度高い(商用向け)今後の主流になる書き方

今なら基本的に :has() がおすすめです。古いブラウザ対応が必要な場合は :checked を選ぶと安心です。

CSSの基本やカスタマイズ方法については、こちらの記事で詳しく解説しています。

HTMLやCSSの編集場所がわからない方は、こちらの記事を参考にしてください。

方法① :checked を使う互換性重視版

ラジオボタンと :checked 擬似クラスを活用する方法。古めの環境も含めて幅広く対応するため、使いやすい方法です。

特徴
  • すべての主要ブラウザで動作IEを除く
  • HTMLに idfor を記述する必要あり(コード量は少し増えるが 互換性は抜群

▶ DEMO(:checked版)

See the Pen タブ切り替え|基本スタイル by Turicco (@Turicco) on CodePen.

<div class="tab-switch">
  <input type="radio" id="tab1" name="TAB" checked>
  <label for="tab1">タブ①</label>
  <div class="tab-content">タブ①の内容</div>

  <input type="radio" id="tab2" name="TAB">
  <label for="tab2">タブ②</label>
  <div class="tab-content">タブ②の内容</div>

  <input type="radio" id="tab3" name="TAB">
  <label for="tab3">タブ③</label>
  <div class="tab-content">タブ③の内容</div>
</div>
.tab-switch {
  --cstm-tab-color:#92bac2;
  display: flex;
  flex-wrap: wrap;
  max-width: 800px;
  margin-inline: auto;
  gap: 0 5px;
}

/* ラジオ非表示 */
.tab-switch input {
  display: none;
}

/* タブボタン */
.tab-switch label {
  padding: 0.7em 1em;
  background:#eee;
  cursor: pointer;
  order: -1;
  text-align: center;
}

/* コンテンツ非表示 */
.tab-content {
  display: none;
  width: 100%;
  padding: 1.5em 0;
}

/* 選択されたタブ+コンテンツ表示 */
.tab-switch input:checked + label {
  background: var(--cstm-tab-color);
  color: #fff;
}
.tab-switch input:checked + label + .tab-content {
  display: block;
}

HTML記述のポイント

  • ラベルとラジオの紐づけ
    id="tab1" と for="tab1" この2行がタブ切り替えの要です。
<!-- タブ①  -->
<input type="radio" id="tab1"  name="TAB" checked>
<label for="tab1">タブ①</label>

<!-- タブ②  -->
<input type="radio" id="tab2"  name="TAB">
<label for="tab2">タブ②</label>

<!-- タブ③  -->
<input type="radio" id="tab3"  name="TAB">
<label for="tab3">タブ③</label>
HTML記述のポイント
  1. inputid を必ずつける
    label for 属性と同じ名前にすることで、クリック時に対応するタブを切り替えられます。
  2. label に for 属性をつける
    for が指定された input をクリックしたのと同じ挙動になります。
    label 自体をクリック可能にできる)
  3. すべての input同じ name を設定する
    → 同じグループ名にすることで、ラジオボタンとして「1つだけ選択可能」にできます。
  4. どれか1つに checked をつける
    → ページ読み込み時に最初に表示するタブを決められます。

CSSのポイント

  • ラジオボタンを非表示
    → ボタンそのものは見せずに、label をタブとしてデザイン。
.tab-switch input {
  display: none;
}
  • 選択中のタブを強調
    :checked 状態の直後にあるラベルを装飾。
.tab-switch input:checked + label {
  background: var(--cstm-tab-color);
  color: #fff;
}
  • 選択中のコンテンツを表示
    → 選択中のラベルの直後にある .tab-content だけ表示されます。
.tab-switch input:checked + label + .tab-content {
  display: block;
}

方法② :has() を使うシンプル実装(モダンブラウザ向け)

:has() を使うと「子要素の状態を見て親要素の見た目を変える」ことができます。

今回は「選択されているラジオボタンを含む label」を判定して、アクティブなタブの色を変更しています。

特徴
  • HTMLが短くシンプルfor 属性や複雑な兄弟関係を使わなくてもOK)
  • CSSの:has()で「選択されているラベル」を簡単に判定
  • ラベルをクリックすると対応するコンテンツを自動表示
  • 一部の古いブラウザでは動作しない場合があります

▶ DEMO(:has版)

See the Pen タブ切り替え|外枠付き by Turicco (@Turicco) on CodePen.

<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>
.tab-switch {
  --cstm-tab-color:#dbb6a2;
  display: flex;
  flex-wrap: wrap;
  max-width: 800px;
  margin-inline: auto;
  gap: 5px;
}

/* タブボタン */
.tab-switch label {
  padding: 0.7em 1em;
  background:#eee;
  cursor: pointer;
  order: -1; /* 上に表示 */
  text-align: center;
}

/* ラジオ非表示 */
.tab-switch input {
  display: none;
}

/* コンテンツ非表示 */
.tab-content {
  display: none;
  width: 100%;
  padding: 1.5em 0;
}

/* 選択されたタブ+コンテンツ表示 */
.tab-switch label:has(:checked) {
  background: var(--cstm-tab-color);
  color: #fff;
}
.tab-switch label:has(:checked) + .tab-content {
  display: block;
}

HTML記述のポイント

  • ラジオボタンをラベル内に書く
    → ラベルをクリックすると input が切り替わり、同時にCSSで状態を判定できます。
<label><input type="radio" name="TAB" checked>タブ①</label>
HTML記述のポイント

すべての input同じ name を設定する。

  • タブ① <input type="radio" name="TAB" checked>
  • タブ② <input type="radio" name="TAB">
  • タブ③ <input type="radio" name="TAB">

CSSのポイント

  • :has(:checked) で選択状態を判定
    label の中に :checked な input がある場合のみ、スタイルを適用。
.tab-switch label:has(:checked) {
  background: var(--cstm-tab-color);
  color: #fff;
}
  • 隣接するコンテンツを表示
    → 選択されたラベルのすぐ後ろにある .tab-content を表示します。
.tab-switch label:has(:checked) + .tab-content {
  display: block;
}
スポンサーリンク

タブのスタイル|カスタマイズ例

タブ切り替えは中身を切り替えるだけでなく、デザイン次第で見やすさも変わります。

ここからは実際によく使うカスタマイズ例を紹介します。

タブ均等幅

タブを横並びにして、均等に幅を分けたいときflex: 1; を指定します。項目数が変わっても自動で幅が調整されるので便利です。

See the Pen タブ切り替え|input表示バージョン by Turicco (@Turicco) on CodePen.

.tab-switch label {
  flex: 1; /* 均等幅 */
}

吹き出し風スタイル

選択中のタブに下向きの小さな三角形を付けて、吹き出し風に見せられます。

今どのタブを選んでいるのか」を直感的に伝えられるデザイン。特にブログ記事の切り替えメニューなどにおすすめです。

See the Pen タブ切り替え|吹き出し風 by Turicco (@Turicco) on CodePen.

.tab-switch label {
  position: relative;
}

/* 吹き出し */
.tab-switch label:has(:checked)::before {
  content: '';
  position: absolute;
  top: calc(100% - 1px);
  left: 50%;
  transform: translateX(-50%);
  width: 18px;
  height: 9px;
  background-color: var(--cstm-tab-color);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}

丸・白抜きスタイル

タブをボタン風にしたい場合は、丸みをつけた白抜きデザインがおすすめです。

See the Pen タブ切り替え|丸み by Turicco (@Turicco) on CodePen.

.tab-switch label {
  border: 1px solid var(--cstm-tab-color); /* 枠線 */
  border-radius: 30px; /* 丸み */
}

枠線の色を var(--cstm-tab-color) にしておけば、サイト全体のテーマカラーに合わせて統一感を出せます。

スポンサーリンク

タブ切り替えを 同ページに複数セット(2つ以上)置く場合

タブ切り替えを1ページに複数セット置く場合は、いくつか注意点があります。

  • ラジオボタンの name 属性はグループごとに固有にする
    ラジオボタンは 同じname を持つと1つしか選べない特性があるため、1つのタブセットごとに違う名前にします
<!-- タブセット1 -->
<input type="radio" name="TAB1" id="tab1-1" checked>
<input type="radio" name="TAB1" id="tab1-2">

<!-- タブセット2 -->
<input type="radio" name="TAB2" id="tab2-1" checked>
<input type="radio" name="TAB2" id="tab2-2">
  • idfor 属性も重複させない
    • <label for="id名"> は対応する <input> と結びつきます。
    • ページ内で同じ id を複数使うと正しく動作しないので、タブセットごと別の id を付けます。
スポンサーリンク

WordPressでタブ切り替えを実装する場合の注意点

WordPressでは、<p><br>が自動挿入されることがあります。

タブ切り替えは「input → label → .tab-content」のような隣接関係を利用しているので、間に不要なタグが入ると正しく動作しません

うまく切り替わらない場合は、次を確認してください。

  • カスタムHTMLブロック内にまとめて記述しているか
  • 不要な改行が入っていないか
  • ブロックエディタで自動的に段落が追加されていないか

特にクラシックエディタでは自動整形が有効になっていることが多く、このケースが発生しやすい傾向があります。

実際に、この不具合でお問い合わせいただいた方のほとんどがクラシックエディタを使っていました。

→ CSSが反映されない原因と対策をチェック

スポンサーリンク

Cocoonの「タブ」ブロックと活用例

ここまでで、HTMLとCSSだけでタブ切り替えを実装する方法を紹介しました。

  • 「Cocoonでコードを書かずに実装したい」
  • ブロックで完結させたい」

という方は、Cocoon標準のタブブロックを使う方法がおすすめです。実際に当サイトでは、Cocoonのタブブロックをベースにデザインを調整して使っています。

ブロック操作で簡単なタブ切り替えの作りから、デザインをワンクリックで選べる便利なカスタマイズまで詳しく解説しています。

タブをトップページや固定ページで活用したい方はこちらの記事もおすすめです。サイト型トップページの中でタブを使うと、記事一覧や更新情報を見やすく整理できます。

タブ切り替えまとめ

HTMLとCSSだけで、シンプルかつ機能的なタブ切り替えを実装できました。

  • :checked方式 → 互換性が高く、古いブラウザでも動作
  • :has()方式 → より直感的に書けるが、モダンブラウザ向け

迷ったらまずは :has() 版がおすすめです。

コードがシンプルで管理しやすく、現在の主要ブラウザでも問題なく動作します。

一方で、古いブラウザ対応が必要な場合は :checked 版を選びましょう。

\シェアはこちらから/
スポンサーリンク
背景画像|PC

About meこの記事を書いた人

はるみです
吹き出し|女性

ブログ好きな40代主婦です。
2020年1月1日にWordPressを始め、
Cocoonをスキンなしでカスタマイズ。

  • ドメインパワー : 45
  • 2023年より有料記事公開
    累計580件のご購入実績
  • カスタマイズを丁寧にサポート

Shopping お買い物はこちら

Comment 記事の感想を書き込んでいただけると幸いです

  1. 匿名 より:

    返信ありがとうございます。

    Cocoonではないのでショートコードは使えないのですが、記事拝見させて頂きました。
    色々と試みてみたのですが、結局、素人にはどの要素をいれるとカテゴリーの記事一覧が表示されるのかわからずでした…

    もう少し頑張ってみます。

  2. 匿名 より:

    コメント失礼します。

    HTMLにある「コンテンツをここに入れる」には何を入れたら良いのでしょうか?

    タブ自体は奇麗に表示されていますが、各タブの下にカテゴリーを表示したいのですが、URLなどを入力するようなものではないようですし…

    他のサイトも拝見したのですが、ここに何を入れるとカテゴリーや記事が表示されるのかわからず質問させて頂きました。

タイトルとURLをコピーしました