CSSのみでタブ切り替え
■ソースコード全体
See the Pen
CSSのみでタブ切り替え by ささ (@mygod877)
on CodePen.
■仕組み
以下の3つの性質を利用することによって、タブ切り替え機能を実現する。
1.ラジオボタンの性質
ラジオボタン<input type="radio">
は複数の要素に同じ名前を付けたときに、
必ず一つだけが選択されるという性質を持つ。
以下のラジオボタンは最初に1が選択されており、2をクリックすると
1の選択が解除されて2にチェックが付く。
1: 2: 3:
2.ラベルタグの性質
ラベルタグ<label>
はfor属性を持ち、inputタグのid名と合わせることで、
ラベルタグをクリックしてもinputタグをチェック状態にすることができる。
<label for="test">ここをクリックしてもチェック状態になる</label>
<input type="checkbox" id="test">
3.CSSセレクタ「:checked」と「+」の性質
セレクタ:checked
を付けると、その要素がチェックされている
状態のときのみスタイルを適用する。
セレクタA + B
とすることで、要素Aに隣接している要素Bのみに
スタイルを適用する。
この3つを組み合わせ以下のような実装を行う。
- ラベルタグをタブにする
- ラジオボタンのinputタグとタブで切り替えるコンテンツのタグを隣接させる
- inputタグを非表示にし、チェックされたinputタグに隣接したコンテンツタグのみ表示する
■コード解説
〇HTML
タブ1の構成要素は3-7行目の以下のとおりである。
<input class="trigger" type="radio" id="tab1" name="tab" checked>
<label class="tab" for="tab1">タブ1</label>
<div class="contents">
<p>タブ1の内容</p>
</div>
上記の説明の通り、ラジオボタンの<input>
、タブを表す<label>
、
タブコンテンツの<div>
が並んでいる。
この時の注意点は以下のとおりである。
<input>
のid属性値と<label>
のfor属性値を一致させる- 切りかえる全てのタブの
<input>
のname属性値を同じものにする - 初期値として表示させるコンテンツの
<input>
にchecked属性を付与する
〇CSS
まず、全体を囲む.tab-contents
に対するスタイルを記述する。
.tab-contents {
display: flex;
flex-wrap: wrap;
}
HTMLは基本的に記述したタグを上から順番に表示していくため、
そのまま表示させると以下のようになる。
これは記述の順番が、
タブ1 > コンテンツ1 > タブ2 > コンテンツ2 > タブ3 > コンテンツ3
となっているからである。
これを解消するために、flexboxと指定し、各タブにorder: -1
を設定する。
そこ以外は見た目に関するスタイルであり、タブ機能には特に関係ない。
.tab {
border-left: 1px solid #52616b;
border-top: 1px solid #52616b;
padding: 3px 15px;
cursor: pointer;
user-select: none;
transition: all 0.2s;
order: -1;
}
.tab:last-of-type {
border-right: 1px solid #52616b;
}
次に、<input>
はタブ切り替えのトリガーの機能しか持たないため、
非表示(display: none
)にしておく。また、タブコンテンツも非表示にする。
.trigger {
display: none;
}
.contents {
display: none;
width: 100%;
background-color: #52616b;
color: #f0f5f9;
padding: 10px
}
最後に、チェックされた<input>
に隣接した要素のスタイルを記述する。
選択されたタブの色を変更し、コンテンツを
表示する設定(display: block
)に上書きする。
.trigger:checked + .tab {
background-color: #52616b;
color: #f0f5f9;
}
.trigger:checked + .tab + .contents {
display: block;
}