サイト型トップページの作り方を公開しています!Check

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

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

通常タブ切り替えはJavaScriptを使って実装するケースが多いですが、実は CSSだけ でも作れます。

この記事では、:checked 疑似クラスや :has() 擬似クラスを活用して、シンプルかつ軽量なタブ切り替えを実装する方法を紹介します。

「HTMLとCSSの基礎が分かる方」を対象としていますが、サンプルコードをそのままコピペすれば 初心者でもすぐ使える ようになっています。

メリット
  • JavaScript不要で軽量
  • WordPressやブログ記事にもコピペで導入可能

「新着記事」と「更新記事」の切り替えに使っています。

スポンサーリンク

About meこの記事を書いた人

はるみです
女性-1-gif

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

  • ドメインパワー : 40
  • 2023年より有料記事公開
    累計500件(月間約20件)のご購入実績
    (2025年9月現在)
  • カスタマイズを丁寧にサポート

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

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

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

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

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

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

▶ CodePenデモ(: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 {
  --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(--tab-color);
  color: #fff;
}
.tab-switch input:checked + label + .tab-content {
  display: block;
}

HTML記述のポイント

  • ラベルとラジオの紐づけ
    for="tab1"id="tab1" を対応させることで、ラベルをクリックするとラジオが切り替わります。
    <!-- タブ①  -->
    <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(--tab-color);
      color: #fff;
    }
    • 選択中のコンテンツを表示
      → 選択中のラベルの直後にある .tab-content だけ表示されます。
    .tab-switch input:checked + label + .tab-content {
      display: block;
    }

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

    2023年以降多くのブラウザで :has() が利用可能になり、さらに直感的に書けるようになりました。

    特徴
    • HTMLが短くシンプルfor 属性や複雑な兄弟関係を使わなくてもOK)
    • CSSの:has()で「選択されているラベル」を簡単に判定
    • ラベルをクリックすると対応するコンテンツを自動表示
    • 注意点:古いブラウザでは動作しない(Firefox 120以前など)
      • 2025年現在、ほぼすべての主要ブラウザでサポートされています

    ▶ CodePenデモ(: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 {
      --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(--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(--tab-color);
      color: #fff;
    }
    • 隣接するコンテンツを表示
      → 選択されたラベルのすぐ後ろにある .tab-content を表示します。
    .tab-switch label:has(:checked) + .tab-content {
      display: block;
    }
    スポンサーリンク

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

    タブ切り替えは「中身の切り替え」だけでなく、デザインを工夫することで見やすさ・使いやすさがアップします。

    ここでは簡単に試せるカスタマイズ例を紹介します。

    タブ均等幅

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

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

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

    吹き出し風スタイル

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

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

    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(--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(--tab-color); /* 枠線 */
      border-radius: 30px; /* 丸み */
    }

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

    スポンサーリンク

    タブ切り替えを 同ページに複数セット置く場合

    タブ切り替えを 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 を付けます。
    スポンサーリンク

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

    WordPressテーマ「Cocoon」では、バージョン2.7.3以降から直感的に使える便利な「タブ」ブロックが追加されました。この機能を使えば、HTMLコードを書かずにタブ切り替えを実装でき、編集画面でそのまま内容を操作できます。

    • 直感的な操作:ブロック内で簡単に編集可能
    • レスポンシブ対応:スマホ・タブレットでも快適

    当サイトでは、タブのデザインをワンクリックで切り替えられるおしゃれなカスタマイズ方法を紹介しています。

    また、Cocoonを使ったサイト型トップページの実装例も公開中です。こちらでは、HTMLとCSSのみでシンプルかつ機能的なタブ切り替えを取り入れ、テーマSWELL風のデザインに仕上げています。

    スポンサーリンク

    まとめ

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

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

    どちらもJavaScript不要で実装できるので、環境や目的に応じて使い分けましょう。

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

    1. 匿名 より:

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

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

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

    2. 匿名 より:

      コメント失礼します。

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

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

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

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