タブを選択すると、対応するコンテンツだけを表示する基本のタブ切り替えを紹介します。HTML・CSS・サンプルの3つのタブがあり、選択したタブの背景色が青色に変わると同時に、下の表示内容が切り替わります。アニメーションは使用せず、クリックすると瞬時に表示が変わります。
今回は、JavaScriptを使う方法と、HTML/CSSのみで実現する方法の2パターンを紹介します。どちらもタブのデザインや表示内容、基本的な操作方法は同じです。JavaScript版では選択に応じて表示内容を切り替え、HTML/CSS版ではJavaScriptを使用せずに同じ動作を実現します。
マウスでのクリック操作に加え、キーボードでも操作できます。TabキーやShift + Tabキーで操作対象へ移動し、左右矢印キーでタブを切り替えられます。デモでは2つの実装方法を切り替えながら、見た目と操作の違いを比較できます。
デモ
タブを選択すると、対応する内容に切り替わります。
タブを選択すると、対応する内容に切り替わります。
「JavaScriptを使う方法」と「HTML/CSSのみ」を切り替え、同じデザインと操作でタブの動作を比較できます。マウスクリックで選択できるほか、Tabキーで次の操作対象へ移動、Shift + Tabキーで前の操作対象へ戻る、左右矢印キーでタブを切り替える、Spaceキーでタブを選択する操作に対応しています。また、上部の実装方法切り替えボタンはEnterキーまたはSpaceキーでも操作できます。
コードをコピーして使おう!
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- 文字コードの設定 -->
<meta charset="UTF-8">
<!-- スマートフォンなどの画面幅に対応 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ページタイトル -->
<title>基本のタブ切り替え</title>
<!-- タブ切り替えのCSSを読み込む -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- タブ切り替え全体 -->
<div class="basic-tab-switch_wrap">
<!-- タイトルと説明文 -->
<div class="basic-tab-switch_title">基本のタブ切り替え</div>
<p class="basic-tab-switch_text">タブを選択すると、対応する内容に切り替わります。</p>
<!--
タブの選択状態を管理するラジオボタン
name属性を共通にすると、3つのうち1つだけ選択できる。
checkedを付けたHTMLタブが初期状態で選択される。
value属性はJavaScriptで表示先を判別するために使用する。
-->
<input class="basic-tab-switch_input" type="radio" name="basic-tab-switch" id="basic-tab-switch_html" value="html" checked>
<input class="basic-tab-switch_input" type="radio" name="basic-tab-switch" id="basic-tab-switch_css" value="css">
<input class="basic-tab-switch_input" type="radio" name="basic-tab-switch" id="basic-tab-switch_sample" value="sample">
<!--
タブの表示部分
各labelのfor属性を対応するラジオボタンのidに合わせる。
クリックすると、そのラジオボタンが選択される。
-->
<div class="basic-tab-switch_tabs" role="group" aria-label="コンテンツの選択">
<label class="basic-tab-switch_tab" for="basic-tab-switch_html">HTML</label>
<label class="basic-tab-switch_tab" for="basic-tab-switch_css">CSS</label>
<label class="basic-tab-switch_tab" for="basic-tab-switch_sample">サンプル</label>
</div>
<!--
タブに対応するコンテンツ
data-panelの値はラジオボタンのvalue属性と一致させる。
初期表示するHTMLのコンテンツにis-activeを指定する。
-->
<div class="basic-tab-switch_panels">
<div class="basic-tab-switch_panel is-active" data-panel="html">
HTMLはWebページの構造を作るためのマークアップ言語です。
</div>
<div class="basic-tab-switch_panel" data-panel="css">
CSSは文字色やレイアウトなど、見た目をデザインするために使います。
</div>
<div class="basic-tab-switch_panel" data-panel="sample">
タブを選択すると、対応するコンテンツだけが表示されます。
</div>
</div>
</div>
<!-- 選択されたタブのコンテンツを表示するJavaScriptを読み込む -->
<script src="script.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- 文字コードの設定 -->
<meta charset="UTF-8">
<!-- スマートフォンなどの画面幅に対応 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ページタイトル -->
<title>基本のタブ切り替え</title>
<!-- タブ切り替えのCSSを読み込む -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- タブ切り替え全体 -->
<div class="html-css-only-tab-switch_wrap">
<!-- タイトルと説明文 -->
<div class="html-css-only-tab-switch_title">基本のタブ切り替え</div>
<p class="html-css-only-tab-switch_text">タブを選択すると、対応する内容に切り替わります。</p>
<!--
タブの選択状態を管理するラジオボタン
name属性を共通にすると、3つのうち1つだけ選択できる。
checkedを付けたHTMLタブが初期状態で選択される。
HTML/CSSのみで動作するため、JavaScriptは使用しない。
-->
<input class="html-css-only-tab-switch_input" type="radio" name="html-css-only-tab-switch" id="html-css-only-tab-switch_html" value="html" checked>
<input class="html-css-only-tab-switch_input" type="radio" name="html-css-only-tab-switch" id="html-css-only-tab-switch_css" value="css">
<input class="html-css-only-tab-switch_input" type="radio" name="html-css-only-tab-switch" id="html-css-only-tab-switch_sample" value="sample">
<!--
タブの表示部分
labelのfor属性を対応するラジオボタンのidに合わせる。
クリックすると、そのラジオボタンが選択される。
-->
<div class="html-css-only-tab-switch_tabs" role="group" aria-label="コンテンツの選択">
<label class="html-css-only-tab-switch_tab" for="html-css-only-tab-switch_html">HTML</label>
<label class="html-css-only-tab-switch_tab" for="html-css-only-tab-switch_css">CSS</label>
<label class="html-css-only-tab-switch_tab" for="html-css-only-tab-switch_sample">サンプル</label>
</div>
<!--
タブに対応するコンテンツ
選択されたラジオボタンのchecked状態をCSSで判定する。
対応するコンテンツだけを表示し、その他は非表示にする。
-->
<div class="html-css-only-tab-switch_panels">
<div class="html-css-only-tab-switch_panel html-css-only-tab-switch_panel-html">
HTMLはWebページの構造を作るためのマークアップ言語です。
</div>
<div class="html-css-only-tab-switch_panel html-css-only-tab-switch_panel-css">
CSSは文字色やレイアウトなど、見た目をデザインするために使います。
</div>
<div class="html-css-only-tab-switch_panel html-css-only-tab-switch_panel-sample">
タブを選択すると、対応するコンテンツだけが表示されます。
</div>
</div>
</div>
</body>
</html>
コードをコピーする場合 使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。 サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
Q ダウンロードしたけど、これをネット上で動かすにはどうするの?
Googleアカウントがあれば、InfinityFreeで無料サーバーを作成して、ダウンロードしたサンプルをネット上で動かせます。
InfinityFreeを初めて利用する場合は①から、すでにサーバーを作成している場合は②へ進んでください。
ファイル構成と設置方法
今回は、JavaScriptを使う方法と、HTML/CSSのみで切り替える方法の2種類を用意しています。 どちらも3つのタブから1つを選択する構成ですが、コンテンツの表示を切り替える仕組みが異なります。 それぞれ独立したサンプルとしてダウンロードできるため、使用したい方法を選んで設置してください。
JavaScriptを使う方法のファイル構成
sample/
├── index.html
├── style.css
└── script.js
HTML/CSSのみの方法のファイル構成
sample/
├── index.html
└── style.css
各ファイルの役割
JavaScriptを使う方法では、index.htmlに3つのラジオボタン、タブのラベル、切り替え対象のコンテンツを配置しています。
style.cssではタブの色や配置、選択状態、コンテンツ領域のデザインを設定し、script.jsで選択されたタブに対応するコンテンツの表示を制御します。
HTML/CSSのみの方法では、index.htmlに同様のタブとコンテンツを配置し、style.cssの:checkedを利用して表示を切り替えます。
JavaScriptによる処理がないため、script.jsは必要ありません。
設置方法・使い方
セクション③から使用したい方法の「サンプル一式をダウンロード」をクリックし、ZIPファイルを展開してください。
JavaScript版ではindex.html、style.css、script.jsを同じフォルダに配置します。
HTML/CSSのみの方法ではindex.htmlとstyle.cssを同じフォルダに配置します。
ファイルを配置したら、index.htmlをブラウザで開いてください。
最初は「HTML」タブの内容が表示されます。
「CSS」または「サンプル」をクリックすると、選択したタブに対応する内容へ切り替わります。
キーボードではTabキーでタブの選択部分へ移動し、矢印キーで選択を変更できます。
2つの方法を同時に設置する必要はありません。
ラジオボタンとタブを対応させる仕組み
どちらの方法も、ラジオボタンとlabel要素を組み合わせています。
ラジオボタンのidとlabel要素のforを一致させることで、タブの文字をクリックしたときに対応するラジオボタンが選択されます。
JavaScript版のindex.htmlでは、次のように設定しています。
<!--
タブの選択状態を管理するラジオボタン
name属性を共通にすると、3つのうち1つだけ選択できる。
checkedを付けたHTMLタブが初期状態で選択される。
value属性はJavaScriptで表示先を判別するために使用する。
-->
<input class="basic-tab-switch_input" type="radio" name="basic-tab-switch" id="basic-tab-switch_html" value="html" checked>
<input class="basic-tab-switch_input" type="radio" name="basic-tab-switch" id="basic-tab-switch_css" value="css">
<input class="basic-tab-switch_input" type="radio" name="basic-tab-switch" id="basic-tab-switch_sample" value="sample">
<!--
タブの表示部分
各labelのfor属性を対応するラジオボタンのidに合わせる。
クリックすると、そのラジオボタンが選択される。
-->
<div class="basic-tab-switch_tabs" role="group" aria-label="コンテンツの選択">
<label class="basic-tab-switch_tab" for="basic-tab-switch_html">HTML</label>
<label class="basic-tab-switch_tab" for="basic-tab-switch_css">CSS</label>
<label class="basic-tab-switch_tab" for="basic-tab-switch_sample">サンプル</label>
</div>
3つのラジオボタンはname="basic-tab-switch"を共通にしているため、同時に複数を選択することはできません。
最初のラジオボタンに付けたcheckedによって、「HTML」が初期状態で選択されます。
タブに表示する文字は、index.htmlのlabel要素内にある「HTML」「CSS」「サンプル」を変更することで編集できます。
HTML/CSSのみの方法でも同じ仕組みですが、クラス名とIDにはhtml-css-only-tab-switchを使用しています。
JavaScriptでコンテンツを切り替える仕組み
JavaScript版では、ラジオボタンの選択状態が変わると、script.jsのchangeイベントが実行されます。
選択されたラジオボタンのvalueと、コンテンツ側のdata-panelを比較して表示先を決定します。
次は、script.jsの切り替え処理です。
// 各ラジオボタンに選択変更時の処理を登録する
inputs.forEach(function(input) {
// ラジオボタンの選択状態が変わると実行する
input.addEventListener("change", function() {
// このラジオボタンが選択されていない場合は処理を終了する
if (!input.checked) {
return;
}
// すべてのコンテンツについて表示状態を更新する
panels.forEach(function(panel) {
// data-panelと選択中のラジオボタンのvalueが一致するか判定する
const active = panel.dataset.panel === input.value;
// 一致したコンテンツだけにis-activeを付け、それ以外からは外す
panel.classList.toggle("is-active", active);
});
});
});
panel.dataset.panel === input.valueで表示するコンテンツを判定し、一致した要素にだけis-activeクラスを付けます。
style.cssでは、このクラスが付いたコンテンツをdisplay: blockで表示し、それ以外は非表示にしています。
コンテンツの文章はindex.htmlのbasic-tab-switch_panel内で変更できます。
対応関係を変更する場合は、ラジオボタンのvalueとコンテンツのdata-panelを同じ値にしてください。
HTML/CSSのみでコンテンツを切り替える仕組み
HTML/CSSのみの方法では、JavaScriptの代わりにCSSの:checkedと後続兄弟セレクタ~を使用します。
選択されたラジオボタンに対応するコンテンツだけを表示するため、次のCSSを設定しています。
/* =========================================
選択中のコンテンツ
========================================= */
/* :checkedと後続兄弟セレクタを使い、選択された内容だけを表示する */
#html-css-only-tab-switch_html:checked ~ .html-css-only-tab-switch_panels .html-css-only-tab-switch_panel-html,
#html-css-only-tab-switch_css:checked ~ .html-css-only-tab-switch_panels .html-css-only-tab-switch_panel-css,
#html-css-only-tab-switch_sample:checked ~ .html-css-only-tab-switch_panels .html-css-only-tab-switch_panel-sample {
display: block; /* 選択中のラジオボタンに対応するコンテンツを表示する */
}
例えば「CSS」のラジオボタンが選択されると、#html-css-only-tab-switch_css:checkedに一致し、html-css-only-tab-switch_panel-cssのコンテンツが表示されます。
選択されていないコンテンツは、共通のhtml-css-only-tab-switch_panelに設定されたdisplay: noneによって非表示のままになります。
この方法ではHTMLの要素の並び順も重要です。
ラジオボタンをコンテンツ領域より前に配置することで、後続兄弟セレクタによる切り替えが成立しています。
タブを追加したりIDを変更したりする場合は、index.htmlのラジオボタンとコンテンツに加えて、style.cssの対応するセレクタも変更する必要があります。
タブとコンテンツ領域のサイズ調整
2つの方法では、同じ数値を使用してタブの表示サイズを設定しています。
JavaScript版のstyle.cssでは、次の設定を使用しています。
/* =========================================
タブ切り替え全体
========================================= */
.basic-tab-switch_wrap {
width: 100%; /* 設置先の横幅に合わせる */
max-width: 700px; /* 最大横幅。大きくするとタブ全体が横に広がる */
margin: 40px auto; /* 上下40pxの余白。左右は自動調整して中央に配置する */
padding: 32px; /* 内側の余白。大きくすると内容と外枠の間隔が広がる */
border: 1px solid #e5e7eb; /* 外枠。1pxを大きくすると線が太くなる */
border-radius: 18px; /* 外枠の角丸。大きくすると丸みが強くなる */
background: #f8fafc; /* 全体の背景色 */
color: #111827; /* 基本の文字色 */
font-family: sans-serif; /* 全体のフォント */
font-size: 16px; /* 基本の文字サイズ。大きくすると文字が大きくなる */
box-sizing: border-box; /* 余白と枠線を横幅に含める */
}
max-width: 700pxはタブ全体の最大横幅です。
数値を大きくすると横に広く、小さくするとコンパクトな表示になります。
padding: 32pxは外枠と内部の内容との間隔で、数値を大きくすると余白が広がります。
タブの高さはbasic-tab-switch_tabのmin-height: 52px、コンテンツ領域の高さはbasic-tab-switch_panelのmin-height: 140pxで調整できます。
どちらも最小高さの指定なので、内容が増えた場合は必要に応じて縦方向に広がります。
HTML/CSSのみの方法では、対応するhtml-css-only-tab-switch_で始まるクラスを編集してください。
レスポンシブ対応
どちらの方法も、全体の横幅をwidth: 100%とmax-width: 700pxで制御し、設置先の横幅に合わせて縮小できるようにしています。
さらに、画面幅640px以下では、タブやコンテンツの余白と文字サイズを調整しています。
JavaScript版のstyle.cssでは、次のメディアクエリを使用しています。
/* =========================================
スマートフォン対応
========================================= */
@media (max-width: 640px) {
/* 画面幅640px以下で全体の余白を調整する */
.basic-tab-switch_wrap {
padding: 24px 18px; /* 上下24px・左右18px。大きくすると枠と内容の間隔が広がる */
}
/* スマートフォンでタブの高さ・余白・文字サイズを調整する */
.basic-tab-switch_tab {
min-height: 48px; /* タブの最小高さ。大きくするとタブが縦に広がる */
padding: 12px 8px; /* 上下12px・左右8px。大きくするとタブ内の余白が広がる */
font-size: 14px; /* タブの文字サイズ。大きくすると文字が大きくなる */
}
/* スマートフォンでコンテンツの余白を調整する */
.basic-tab-switch_panel {
padding: 20px 16px; /* 上下20px・左右16px。大きくすると文字と枠線の間隔が広がる */
}
}
画面幅640px以下では、タブの文字サイズを16pxから14pxに、最小高さを52pxから48pxに変更しています。
3つのタブは横並びのまま、狭い画面でも表示しやすいサイズになります。
切り替えの基準となる640pxを変更すると、スマートフォン向けのスタイルを適用する画面幅を調整できます。
HTML/CSSのみの方法にも同じ数値のメディアクエリがあり、クラス名だけが異なります。
コメント