タブ押すと画像切り替わる仕組み(CSS)

ボタンを押すとページ内の画像が切り替わる仕組みです。前までJSでやるものだと思ってましたが、CSSでシンプルに実装出来るとの事で調べました。以下備忘録

HTMLコードはこんな感じ。CSSのレイアウト調整は割愛

<body>
 <div class="area">
 
   <input type="radio" name="tab_name" id="tab1" checked>
   <label class="tab_class" for="tab1">画像A</label>
   <div class="content_class">
     <img src="imgs/kani.png">
   </div>
   
   <input type="radio" name="tab_name" id="tab2" >
   <label class="tab_class" for="tab2">画像B</label>
   <div class="content_class">
     <img src="imgs/toufu.png">
   </div>
   
 </div>
</body>
.content_class {
 display: none;
}

input:checked + .tab_class + .content_class {
 display: block;
}

実装する前に全体のイメージを考えます。漠然と動いてもだいたい良い事は無いです。

【やりたい事】
AとBの画像があり、ユーザーがボタンを押すとページ内のAの画像がBに切り替わって欲しい

【そのために】
①ボタンを作成する
②画像コンテンツを作成する
③一旦画像コンテンツを全部非表示にする
④選択されたボタンのコンテンツだけ表示する
何か出来そうですね。

ボタン作る

HTMLにはinputタグという便利なものがあります。フォームでよく見る選択できるボタン(ラジオボタン)とか、入力欄とか用意出来るものです。
input  type="radio"を使って画像A、画像Bの選択肢を作るためのラジオボタンを用意します。

<input type="radio" name="tab_name" id="tab1" >
<input type="radio" name="tab_name" id="tab2" >

inputだけだとラジオボタンの○部分しか押したときに反応出来ないので、タグっぽく文字とラジオボタンが連動するように、labelタグを使います。

<input type="radio" name="tab_name" id="tab1" >
<label class="tab_class" for="tab1">画像A</label>

<input type="radio" name="tab_name" id="tab2" >
<label class="tab_class" for="tab2">画像B</label>

for属性とid名を同じにすると、labelの要素を押されても、inputのラジオボタンをチェックした事と同じ結果が得られます。

画像コンテンツを作成する

説明する事もないですが、ボタンとコンテンツが連動出来るようにクラス名をつけてください。

<input type="radio" name="tab_name" id="tab1" >
<label class="tab_class" for="tab1">画像A</label>
<div class="content_class">
 <img src="imgs/kani.png">
</div>

<input type="radio" name="tab_name" id="tab2" >
<label class="tab_class" for="tab2">画像B</label>
<div class="content_class">
 <img src="imgs/toufu.png">
</div>

一旦画像コンテンツを全部非表示にする

このままだと画像AとBが両方表示されてるだけの状態になりますので、一旦全部非表示にします。コンテンツのクラス名に対して、表示を消すdisplay:noneをcssでかけておきます。

.content_class {
 display: none;
}

選択されたボタンのコンテンツだけ表示する

一番大事な所。ボタンを押したときに連動してコンテンツを表示するにはどうするか?という場面。
ラジオボタンにチェックが入っている(選択されている)状態の時、コンテンツを表示すると命令する。

.content_class {
 display: none;
}

input:checked + .tab_class + .content_class {
 display: block;
}

input:checkedという便利なものがありました。inputで作成した選択肢が選ばれた時、という限定的なシチュエーションを作る疑似クラスセレクター
+は隣接兄弟結合子という隣接セレクタ。これによって、

選択されたラジオボタンの兄弟要素、div class="content_class"のコンテンツをブロック要素として表示させる。と出来ます。

要は選択されたボタンのコンテンツだけ表示する、という結果になります。

ゼロ知識でコピペすると、やらかす箇所

Q.inputのcheckedって?
A.チェックが入っている状態の属性。radioボタンについては、必ずどれか1つに checked属性を指定しなければ、未定義となるそうです。怖いので、デフォルトで表示させる方にcheckedを入れてます。

例:Aの画像だけデフォで表示させたい

<input type="radio" name="tab_name" id="tab1" checked>
<label class="tab_class" for="tab1">画像A</label>
<div class="content_class">
 <img src="imgs/kani.png">
</div>

<input type="radio" name="tab_name" id="tab2" >
<label class="tab_class" for="tab2">画像B</label>
<div class="content_class">
 <img src="imgs/toufu.png">
</div>

Q.同じようなコンテンツを複数用意したいので、コピペで作成したら全然タブを押しても動かなくなった。
A.idのせい。

ボタンにはそれぞれ別のidをつけなければ、別のボタンとして認識しないのでとんでもない動きをしたり、動かなかったりする。
また、今回はlabelとinputを連動させてるので、forとid名が違うと、違うボタンがcheckedになって想定外の動きをするので、ただコピペすれば良い訳じゃないです。

Q.コピペしたらデフォルトのcheckedが効かなくなった。
A.nameのせい。

checked属性は同じname属性の値をもつラジオボタンで1つしか選択出来ないという事なので、ただコピペして複製しようとすると、checkedが上手く機能しません。同じようなコンテンツを複製したい場合は、name属性を別の言葉にかえておきましょう。

<div>
    <input type="radio" name="tab_name1" id="tab1" checked>
    <label class="tab_class" for="tab1">画像A</label>
    <div class="content_class">
     <img src="imgs/kani.png">
    </div>
    
    <input type="radio" name="tab_name1" id="tab2" >
    <label class="tab_class" for="tab2">画像B</label>
    <div class="content_class">
     <img src="imgs/toufu.png">
    </div>
</div>

<div>
    <input type="radio" name="tab_name2" id="tab3" checked>
    <label class="tab_class" for="tab3">画像A2</label>
    <div class="content_class">
     <img src="imgs/kusabi.png">
    </div>
    
    <input type="radio" name="tab_name2" id="tab4" >
    <label class="tab_class" for="tab4">画像B2</label>
    <div class="content_class">
     <img src="imgs/fugu.png">
    </div>
</div>



この記事が気に入ったらサポートをしてみませんか?