動くCSSのためのメモ。
タブコンテンツ

タブボタンをクリックすることで、表示する内容を切り替えるタブコンテンツも、CSSだけでできちゃいます。コンテンツの切り替わり方のバリエーションや、タブボタンで表示レイアウトを切り替えるみたいな使い方など、CSSで作るタブコンテンツについてのまとめです:)

CSSで切り替える仕組み

CSSで切り替えを行うためには、ちょっとした下ごしらえが必要なので、まずはその仕組みについて、下の仕組みがよくわかるサンプルのソースコードを見ながら要点を解説です。

HTML

まずはタブボタンと、それに付随するコンテンツを設置します。
タブボタンに<label>を使うのがポイントです:)

<ul class="tabBtn">
	<li><label for="tab-1">タブ1</label></li>
	<li><label for="tab-2">タブ2</label></li>
	<li><label for="tab-3">タブ3</label></li>
	<li><label for="tab-4">タブ4</label></li>
	<li><label for="tab-5">タブ5</label></li>
</ul>
<div class="tabContents">
	<section>タブコンテンツ1</section>
	<section>タブコンテンツ2</section>
	<section>タブコンテンツ3</section>
	<section>タブコンテンツ4</section>
	<section>タブコンテンツ5</section>
</div>

次に、コンテンツを切り替えるスイッチの役割となる<input type="radio">(ラジオボタン)を5つ、上記ソースコードの手前に設置します。

<input type="radio" name="switch" id="tab-1" checked>
<input type="radio" name="switch" id="tab-2">
<input type="radio" name="switch" id="tab-3">
<input type="radio" name="switch" id="tab-4">
<input type="radio" name="switch" id="tab-5">

name属性の値を統一して、ラジオボタンをひとつのグループに(ここではswitchに)します。それから<input>id属性の値を、<label>for属性の値と同じにして、タブボタンとラジオボタンを関連付けます。
ひとつめの<input>にはchecked属性を付けて、初期状態ではタブコンテンツ1が開いているようにしておきます。
以上で下ごしらえ完了!

CSS

そして、以降の指定が、コンテンツの表示/非表示を切り替えるための仕組みの部分になります。
まずは、タブボタンを切り替えた時の、ボタンのスタイルを指定します。

#tab-1:checked ~ .tabBtn label[for="tab-1"],
#tab-2:checked ~ .tabBtn label[for="tab-2"],
#tab-3:checked ~ .tabBtn label[for="tab-3"],
#tab-4:checked ~ .tabBtn label[for="tab-4"],
#tab-5:checked ~ .tabBtn label[for="tab-5"] {
	background: indianred;
}

1行めを分解して見てみます。
#tab-1:checkedは「id属性がtab-1の要素がチェックされている状態」を選択します。
~チルダは、一般兄弟結合子(間接結合子)といって、セレクタの間にこの記号を挟むと、「左側のセレクタより後に書かれた兄弟要素(同じ階層にある要素)である右側のセレクタ」を選択することになります。
最後のlabel[for="tab-1"]は、「for属性がtab-1のlabel要素」を選択します。

つまり、「チェックされている#tab-1要素より後に書かれた、同じ階層にある.tabBtn要素の中の、for属性がtab-1のlabel要素」にbackground: indianredを指定するって事になります。
要するに「1つめのラジオボタンがチェックされてる時は、1つめのタブボタンを赤くする」ということ;)

1つめのタジオボタンがcheckedの時は、1つめのラブボタンの色が変わる

タブボタンを切り替えた時のコンテンツのスタイルもタブボタンと同じ要領で、「チェックされている#tab-1要素より後に書かれた、同じ階層にある.tabContents要素の中の、ひとつめのsection要素」というように、タブコンテンツを特定します。

.tabContents section {
	opacity: .1;
}
#tab-1:checked ~ .tabContents section:nth-child(1),
#tab-2:checked ~ .tabContents section:nth-child(2),
#tab-3:checked ~ .tabContents section:nth-child(3),
#tab-4:checked ~ .tabContents section:nth-child(4),
#tab-5:checked ~ .tabContents section:nth-child(5) {
	opacity: 1;
	background: white;
}

チェックされていない時は透明(ここでは仕組みが見えるように半透明)にしておき、チェックされたボタンを不透明にすることで、表示/非表示が切り替わるって寸法です。

ページトップへ戻る

:targetを使ってタブコンテンツ

上の「仕組みがよくわかるサンプル」では、ラジオボタンを使ってコンテンツの表示/非表示を切り替えてましたが、アンカーリンクを使っても、同じように切り替える事ができます。

例えばURLの末尾に「#contents-1」と付けてリンクすると、ページ内の<div id="contents-1">の位置へリンクする事ができますよね。id属性を持った要素はすべてアンカーポイントとなって、その要素の場所へリンクできるようになります。
そんなアンカーリンクされている要素に、スタイルを適用する事ができるのが:targetという疑似クラス。
下記のように指定すれば、URLの末尾が「#contents-1」としてアクセスした時に、contents-1というid属性を持った要素を赤いボーダーで囲みます。

#contents-1:target {
	border: 2px solid indianred;
}

URLを利用してスタイルを適用しているので、アンカーリンクする度に特定の要素のスタイルを切り替えることが可能です。しかもURLが切り替わるから、ブラウザの戻るボタンで履歴を辿る事もできちゃいます。タブコンテンツの内容が濃い場合にはこちらの方法が持ってこいかもしれませんねー:D

URL末尾の#ハッシュの値によって、タブボタンの色が変わる

先ほどの、仕組みがよくわかるサンプル:checkedで切り替えてた部分を、:targetで切り替わるように修正してみましょう。

HTML

<input type="radio">だったところを<div>に置き換えます。あくまでスイッチの役割を担う空っぽdiv要素になります。id属性はそのままに、name属性の代わりにclass属性でswitchという値を付与しました。

input要素をdiv要素に変える
<input type="radio" name="switch" id="tab-1" checked>
	⇓
<div id="tab-1" class="switch"></div>

タブボタンは<label>から<a>に置き換えて、for属性でinput要素と紐付けてたところを、今度はhref属性にして、前述の<div>へそれぞれリンクするようにします。

label要素をa要素に変える
<li><label for="tab-1">タブ1</label></li>
	⇓
<li><a href="#tab-1">タブ1</a></li>

CSS

アンカーをクリックすると、ウィンドウの位置がその要素の位置まで移動しちゃいますが、その要素にdisplay: noneを指定すれば移動しなくなります。

ウィンドウ位置を移動させないための指定
.switch {
	display: none;
}
あとは、HTMLに倣ってlabelだったところをaに、forだったところをhrefに、:checkedだったところを:targetに置き換えれば完了ー!

タブボタン
.tabBtn li label { ... }
	⇓
.tabBtn li a { ... }
.tabBtn li label:hover { ... }
	⇓
.tabBtn li a:hover { ... }
#tab-1:checked ~ .tabBtn li [for="tab-1"] { ... }
	⇓
#tab-1:target ~ .tabBtn li [href="#tab-1"] { ... }
タブコンテンツ
#tab-1:checked ~ .tabContents section:nth-child(1) { ... }
	⇓
#tab-1:target ~ .tabContents section:nth-child(1) { ... }

タブを切り替えた後でブラウザの戻るボタンを押してみてください。URLを移動することでタブの表示を切り替えてるので、タブ切り替えが履歴として残るため、切り替える前のタブに戻ることができるんですね;)

ページトップへ戻る

アニメーションして切り替わる

タブコンテンツにコンテンツを入れてみました。

タブコンテンツも、マウスオーバーエフェクトの時みたく、transitionを使って切り替わり方をアレンジすれば、印象的な表現ができちゃいます:)

スライドして切り替わる

タブボタンの切り替えに合わせて、<div class="tabContents">の位置を上下にズラせば、スクロールコンテンツみたいなものもお手のもの。

タブボタンに対応するタブコンテンツの位置

上図のように、あらかじめtransform: translateY()で、タブボタンに対応するコンテンツの位置を指定しておきます。例えば下記なら、「タブ2」がチェックされてる時には、.tabContentsを上へ20%ズラす、ということ。.tabContents全体の高さを100%とした20%分。

#tab-2:checked ~ .tabContents {
	transform: translateY(-20%);
}

これをタブコンテンツ分(このサンプルでは5つ)用意し、transitionを適用すれば、上下にスライドしながらコンテンツが切り替わるようになります。

あれれ…、タブコンテンツがタブボタンの上に被さってタブボタンが押せなくなっちゃう…X(。。

タブボタンをタブコンテンツより手前の階層に

こんな時は.tabBtnz-indexを指定して、手前に配置すれば安心。

.tabBtn {
	position: relative;
	z-index: 1;
}

z-indexpositionプロパティstatic以外の値が指定してある要素でないと効果がないので、position: relativeも一緒に指定。

無事タブボタンが押せるようになりました:D

横にスライドして切り替わる

タブコンテンツを横並びにして、transform: translateX()で横へズラせば、横スライドもお手のもの。

.tabContentsの横幅20%分ずつスライドする

.tabContentsの横幅をウィンドウ幅5つ分(500%)にして、その中にタブコンテンツを横並びにします。そのままだとスクロールバーが出てしまうので、全体を包む<div id="wrapper">overflow: hiddenを指定して、スクロールバーを出さないようにすればできあがり。

ページトップへ戻る

表示モード切り替え

ここまでは、いくつかのコンテンツをタブボタンで切り替えてましたが、タブボタンのON/OFFで、同一コンテンツのスタイルを変えるようにすれば、表示モード切り替えみたいな事もできます。

ここでは、「画像とテキスト全部入りのレイアウト」、「画像が主役のレイアウト」、「テキストのみのレイアウト」の3タイプの表示モードを、タブボタンで切り替えてみます。

下記のような記述で、各モード専用のスタイルを用意しておけば、チェックされているタブボタンに合わせて、指定したスタイルが適用される仕組みです。

#normalList:checked ~ .menu elements {
	/* 全部入り用のスタイル */
}
#imageList:checked ~ .menu elements {
	/* 画像が主役用のスタイル */
}
#textList:checked ~ .menu elements {
	/* テキストのみ用のスタイル */
}

アニメーションを加える

上のサンプルだと、transitionを指定してる所だと、前のモードのスタイルがちょっと見えちゃったり、モードの切り替わり方がちょっとかっこわるいですよね…。
下記のようにアニメーションを定義して、タブボタンが:checkedになった時に一度だけ再生するようにしてみます。
@keyframesで、ちょっと間を置いてからフェードインするアニメーションを用意してみました。

@keyframes fadeIn {
	0% { opacity: 0; }
	30% { opacity: 0; }
	100% { opacity: 1; }
}

このアニメーションを、チェックされた時のコンテンツに適用します。

input:checked ~ .menu {
	animation: fadeIn 1s;
}

ページが開いた時に一度だけフェードインしますが、タブボタンで切り替える時には、アニメーションが再生されませんね…:(:checkedされるタブが切り替わっても「fadeIn」というアニメーションはすでに再生された後なので、それ以上は再生されないみたいです…。
そこで、下のサンプルでは、同じアニメーションを各タブ用に3つ用意して、各タブごとに違うアニメーションを指定してみます。
あと、最初にちょっと間を置くのは、animation-delayプロパティで調整することにして、アニメーション自体はフェードインするだけのものに修正します。

#normalList:checked ~ .menu {
	animation: fadeIn 1s .3s both;
}
#imageList:checked ~ .menu {
	animation: fadeIn2 1s .3s both;
}
#textList:checked ~ .menu {
	animation: fadeIn3 1s .3s both;
}
@keyframes fadeIn {
	from { opacity: 0; }
	to { opacity: 1; }
}
@keyframes fadeIn2 {
	from { opacity: 0; }
	to { opacity: 1; }
}
@keyframes fadeIn3 {
	from { opacity: 0; }
	to { opacity: 1; }
}

:checkedされるタブが変わる度に再生するアニメーションも切り替えることで、タブを切り替える度にアニメーションが再生されるようになりましたね:D

Comment & Pingback

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください