jqueryを使わないcssだけで実装するアコーディオンメニュー
アコーディオンメニュー
※高さを内容に合わせたいと言うコメント頂いた為、ちょっぴり編集しました。
アコーディオンメニューとは、クリック(タップ)すると隠れていたメニューが出てくるヤーツです。
スマフォ用のナビゲーションとかにも使われていたりしますね。
あーたむ説明がへたくそすぎて分かんない…
とっつぁんはいはい、そうでしょうとも。
とりあえずデモを用意したので見てみてください。
あーたむなるほど、うにょーん!ってなるやつね
今まではこういうメニューはjqueryを使うのがわりと一般的でした。
が、htmlとcssだけでも実装できるのよ、という時代になって来たのでご紹介。
ちなみにクソブラウザ(ワタクシのスマフォ標準ブラウザ)でも動きます。
ひとまずコピペでオッケーです。
チェックボックスを使用したアコーディオンメニュー
html
<div class="ac_menu"> <label for="nav01">メニュー1</label> <input type="checkbox" id="nav01" class="bellows" /> <ul> <li><a href="">ナビ01</a></li> <li><a href="">ナビ02</a></li> <li><a href="">ナビ03</a></li> <li><a href="">ナビ04</a></li> </ul> <label for="nav02">メニュー2</label> <input type="checkbox" id="nav02" class="bellows" /> <ul> <li><a href="">ナビ01</a></li> <li><a href="">ナビ02</a></li> <li><a href="">ナビ03</a></li> <li><a href="">ナビ04</a></li> </ul> </div>
css
label { padding :10px 0 0 10px; display: block; margin: 0; color :#fff; background :#333; border: 1px solid #ccc; border-top-left-radius: 10px; -webkit-border-top-left-radius: 10px; -moz-border-radius-topleft: 10px; border-top-right-radius: 10px; -webkit-border-top-right-radius: 10px; -moz-border-radius-topright: 10px; cursor :pointer; } input[type="checkbox"].bellows{ display: none;/* チェックボックスの非表示 */ } .ac_menu ul { /* メニュー開閉時アニメーション */ background :#f4f4f4; -webkit-transition: all 0.5s; -moz-transition: all 0.5s; -ms-transition: all 0.5s; -o-transition: all 0.5s; transition: all 0.5s; margin: 0; padding: 0; list-style: none; } .ac_menu li { padding: 5px; } /* ▽▽アコーディオン開閉指定▽▽ */ input[type="checkbox"].bellows + ul{ max-height: 0;/* チェックが入っていない時の高さ */ overflow: hidden; } input[type="checkbox"].bellows:checked + ul{ max-height: 50em;/* チェックが入っているときの高さ */ } /* △△アコーディオン開閉指定△△ */
- チェックボックスを用意し、チェックが入っているときはメニューが開き、チェックが入っていない時はメニューを閉じる
- チェックボックスはdisplay:none;で非表示にする
- 非表示のチェックボックスにチェックを入れる為に、labelタグのforにチェックボックスのidを指定する
- 隣接セレクタ(+)を使って「チェックが入っている+ul」のheight指定でメニューの開閉を操作
- 開閉時はtransitionでアニメーションさせる
ざっくり説明するとこういう感じです。
1か所が開いているときは他のメニューは閉じたい
1か所開いたらもう1か所は閉じる、ってな動きも定番ですよね。
そういうのはラジオボタンを使うと出来ます。ほら、ラジオボタンって1か所しか選択できないじゃないですか。
html(type属性がradioに、name属性にラジオボタン共通の指定を。)
<div class="ac_menu"> <label for="nav03">メニュー1</label> <input type="radio" name="radio" id="nav03" class="bellows" /> <ul> <li><a href="">ナビ01</a></li> <li><a href="">ナビ02</a></li> <li><a href="">ナビ03</a></li> <li><a href="">ナビ04</a></li> </ul> <label for="nav04">メニュー2</label> <input type="radio" name="radio" id="nav04" class="bellows" /> <ul> <li><a href="">ナビ01</a></li> <li><a href="">ナビ02</a></li> <li><a href="">ナビ03</a></li> <li><a href="">ナビ04</a></li> </ul> </div>
css
label { padding :10px 0 0 10px; display: block; margin: 0; color :#fff; background :#333; border: 1px solid #ccc; border-top-left-radius: 10px; -webkit-border-top-left-radius: 10px; -moz-border-radius-topleft: 10px; border-top-right-radius: 10px; -webkit-border-top-right-radius: 10px; -moz-border-radius-topright: 10px; cursor :pointer; } input[type="radio"].bellows{ display: none;/* チェックボックスの非表示 */ } .ac_menu ul { /* メニュー開閉時アニメーション */ background :#f4f4f4; -webkit-transition: all 0.5s; -moz-transition: all 0.5s; -ms-transition: all 0.5s; -o-transition: all 0.5s; transition: all 0.5s; margin: 0; padding: 0; list-style: none; } .ac_menu li { padding: 5px; } /* ▽▽アコーディオン開閉指定▽▽ */ input[type="radio"].bellows + ul{ max-height: 0;/* チェックが入っていない時の高さ */<br> overflow: hidden; } input[type="radio"].bellows:checked + ul{ max-height: 50em;/* チェックが入っているときの高さ */ } /* △△アコーディオン開閉指定△△ */
cssはcheckboxの時とほぼ変わってません、checkboxがradioに変わってるだけです。
htmlのinput要素のtypeがラジオボタンになっている事と、ラジオボタンには共通のname属性を付けているくらいなものです。
はじめから開いているアコーディオンにするには?
チェックボックスやラジオボタンにチェックが入っているとメニューが開きます。
つまりデフォルトでチェックが入っている状態にすれば初めから開いたメニューになります。
って事でinput要素部分にcheckedを入れればオッケーです。
Pingback: CSSだけでハンバーガーメニュー【jqueryは使わない】 – 飲食店のホームページ制作研究所「とっつぁんブログ」
atsushi
2016年10月17日 at 3:24 PM
とっつぁんさんへ
はじめまして、cssでつくるアコーディオンメニューを調べていてこの記事にたどり着きました。
初心者で困っておりましたが、内容がとてもわかりやすかったおかげで無事に動作できました。
ありがとうございます!
そして…恐れ入りますがひとつお尋ねがあります。
私が参考にさせていただいたのは上記の「チェックボックス」の方です。チェック時に「height: 170px」が表示される、というあり方になっていますが、これを不規則な高さに対応させることはできませんでしょうか?
というのが、当方のメニューはごとにの個数が変わってしまうのです…
考えられる範囲で試してみましたがどうにもうまくいかず…お知恵をお借りできればと思いコメントしました。
ご都合の良い時にアドバイスをいただけたら幸いです。
とっつぁん
2016年10月20日 at 11:45 PM
確かに今時は中のコンテンツに合わせたいですよねw
チェックがある時の高さをautoに設定すれば一応動作するけれど
それだとアニメーションが無効になってしまいます。
そこで以下のようにCSSを変更すれば解決するのではないかと思います。
input[type=”checkbox”].bellows + ul {
max-height: 0; /* 高さではなく最大を0に */
overflow: hidden;
}
input[type=”checkbox”].bellows:checked + ul {
max-height: 50em;/* 数値は適当に… */
}
お役にたてれば幸いです。
atsushi
2016年10月22日 at 2:12 PM
とっつぁんさん
アドバイスいただきありがとうございます!
max-heightだったんですね、無事解決しました!
おかげさまで期待通りの結果が得られました。ありがとうございます!!
コメント欄からですみませんが、お礼申し上げます!!
追伸/私の質問を見返すと…誤植がありますね、大変失礼いたしました。。。
「当方のメニューは項目ごとに…」というつもりでしたが、意味が伝わっていてよかったです!