input
とlabel
でアコーディオンつくった
input
とlabel
を使って、CSSだけでアコーディオンを作ったので備忘録として書くぞ。
See the Pen CSSでアコーディオン作る by mame_hashbill (@mayu-mameuda) on CodePen.
ちなみに領域外クリックでアコーディオン閉じるようにしたぞい。
これからCSSでアコーディオン作ろうとしてる人、なるべくコピペでなんとかなるようなシンプルな記述にしたので、べろっとコピって使ってもらえたら嬉しいぞい。
inputとlabelの関係性
(以前の記事に書いたやつとだいたい同じこと書く。
以前の記事→[HTML/CSS]チェックボックスの仕組みを使ってえだまめ無限プチプチをつくるぞ)
さて、今回使うinput
とlabel
は、よくお問い合わせフォームとかで
チェックボックスとかラジオボタンとかを作るときに使うやつだよな。
このinput
とlabel
は、id
とfor
で関連づけることができて、
関連付けをするとlabel
をクリックしても選択ができる(input
部分にチェックがつけられる)ぞ。
こんな感じに。↓
See the Pen
rNamJmo by mame_hashbill (@mayu-mameuda)
on CodePen.
<inputtype="checkbox"name="choice"id="choice-1"checked><labelfor="choice-1">選択肢1</label><inputtype="checkbox"name="choice"id="choice-2"><labelfor="choice-2">選択肢2</label><inputtype="checkbox"name="choice"id="choice-3"><labelfor="choice-3">選択肢3</label>
で、CSSでアコーディオンを作る上で重要なポイントは、input
またはlabel
をクリックしたとき、checked
っていう状態が付与される点だな。
つまり、checked
がついてる時はアコーディオンが開いていて、
ついてない時は閉じてる、っつう指定をしていくのだ。
HTML
使うHTMLはこんな感じ。
<body><inputtype="checkbox"name="accordion"id="accordion"><labelclass="overlay"for="accordion"></label><divclass="accordion"><labelclass="accordion__heading"for="accordion"><spanclass="accordion__icon"></span>title</label><divclass="accordion__item-wrap"><divclass="accordion__item">hogehoge</div><divclass="accordion__item">fugafuga</div><divclass="accordion__item">hogehoge</div><divclass="accordion__item">fugafuga</div></div></div></body>
input
が1つとlabel
が2つ、上の方にいるな。
.overlay
は領域外クリックの時に使うlabel、.accordion__heading
はアコーディオン開閉に使うlabel。
ほんで、input
はこの2つのlabel
とid="accordion"
で結びついてるぞ。
titleクリックで矢印アイコンの向きを変える
矢印アイコンは、アコーディオンが開いた時にぐるっと上下が反転するようになってるよな。
この仕組みもアコーディオン開閉と仕組みは一緒なので、先にこっちを説明していく。
<inputtype="checkbox"name="accordion"id="accordion"><divclass="accordion"><labelclass="accordion__heading"for="accordion"><spanclass="accordion__icon"></span>title</label></div>
アイコンを動作させるのに必要なHTMLはこれだけ。
で、Scss。
$purple:#3B3955;%accordion,.accordion{&__heading{position:relative;}&__icon{&:before{//アコーディオンの矢印をCSSで作成content:" ";position:absolute;left:20px;top:16px;width:5px;height:5px;border:3pxsolid;border-color:transparent$purple$purpletransparent;transform:rotate(45deg);}}}input[name="accordion"]{display:none;//ラジオボタンを消す}#accordion:checked~{.accordion.accordion__icon{&:before{//check入ったときにアイコンを回転transform:rotate(-135deg);top:23px}}}
アイコン自体をCSSで作成してしまっている関係で:before
の中にたくさん書いてあるのだけど、その辺の説明はこのサイトを参考にしたので、何してるか知りたい人は見てほしい。
→【CSS】CSSのみで三角と矢印を作る方法
さてさて、.accordion__icon
では、
とりあえず閉じている状態の下矢印アイコンを作成しているぞ。
で、そのあとの記述でinput
をdisplay:none;
してるんだけど、
これは、今回はlabel
クリックでchecked
が付与される仕組みを使いたいだけで、input
自体は画面に存在している必要がないためだぞ。
チェック入ったときの指定方法
ほんで、input
を消したあとの記述で、label
をクリックしたとき(checked
付与状態、つまりアコーディオン開いてる状態)の時のアイコンの指定をしているよ。checked
状態の指定は、checked ~
に続けて書くのがお約束。
~
は、間接セレクタっていうやつで、
兄弟関係にあれば間に別の要素が入っても指定ができる便利なセレクタだぞ。
【参考】間接セレクタ (E ~ F)
このセレクタの注意点としては、~
の後に指定するのは、必ず同階層にある要素にしないといけない決まりなので
アイコンをぐるっと回転させるには、#accordion:checked ~ .accordion__icon
という指定にせず、#accordion:checked~ .accordion .accordion__icon
という指定にしないときかないんだなぁ。
ちなみにlabel
がinput
の上にあったりしてもきかないので注意である。
アコーディオンを開閉させる
上と同じ仕組みを使って、いよいよアコーディオン開閉を作る。
HTMLは上に貼ったもの。
で、Scssはこんな感じ(アコーディオン開閉部分のみ抜き出してます)
%accordion,.accordion{&__heading,&__item{padding:020px040px;line-height:50px;letter-spacing:0.05em;}&__heading{background:white;color:$purple;font-weight:bold;position:relative;display:block;cursor:pointer;font-size:18px;}&__item-wrap{overflow:hidden;//これをやらないと中身が表示されちゃうので入れる}&__item{height:0;//閉じてるときは高さを0にしておくbackground:$purple;color:white;}}#accordion:checked~{.accordion.accordion__item{height:50px;transition:height.5s;}}
ポイントとしては2点で、
1. .accordion__item-wrap
にoverflow:hidden;
して、はみ出た部分の表示(.accordion__item
)を隠す。
2. .accordion__item
をheight:0;
にして、checked
が付与された時にheight:50px;
にアニメーションさせる。
これでアコーディオンが開閉するようになるぞ。
この作り方だと、.accordion__item
にアニメーションの秒数指定をしているから、
項目がいくつ増えても指定した秒数で開閉できるのだ。
領域外クリックでアコーディオンを閉じる
最後に領域外クリックでアコーディオンを閉じる指定の仕方。
.overlay
を領域いっぱいにかけてから、pointer-events: none;
で、ポインタの動作を全て無効化する。
この指定を入れることで、要素自体はあるけどクリックはできないようにできるぞ。
で、input
にchecked
が付与されたあと、pointer-events: auto;
でポインタの動作をデフォルトに戻して、.overlay
を押せるようにするぞい。
<inputtype="checkbox"name="accordion"id="accordion"><labelclass="overlay"for="accordion"></label>
.overlay{pointer-events:none;//ポインタの動作全部無効化width:100%;height:100%;position:fixed;top:0;right:0;z-index:-1;}#accordion:checked~{.overlay{pointer-events:auto;//ポインタの動作デフォルトに戻す}}
こんな感じで、領域外をクリックしてもアコーディオンが閉じるようになる。
まとめ
アコーディオンが2つとか3つとかになると、領域外クリックで閉じるやつは無理なのかもしれない。。
その場合はやっぱりJSになっちゃうのかな〜〜〜〜〜〜〜・・・教えて詳しい人よ