こんにちは!セミマサです。
クリックで開け閉めできるアコーディオンメニューは多くのウェブサイトで見かけますよね!今回はjQuery6パターン、HTML5のみ1パターン、CSSのみで2パターン、計9パターンのアコーディオンメニューを作ったので作成方法をまとめていきたいと思います。
※ソースに関して:複数回登場するクラス(accordion-inner等)は初出の部分にのみcssを記載しています。
jQuery/6パターン
複数開けるタイプ
よくあるタイプのアコーディオンメニューです。
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <divclass="accordion-inner"> <h3class="heading">複数開けるタイプ</h3> <divclass="accordion-box column"> <pclass="accordion">アコーディオンA</p> <divclass="accordion-content"> アコーディオンの中身です </div> </div> <divclass="accordion-box column"> <pclass="accordion">アコーディオンB</p> <divclass="accordion-content"> アコーディオンの中身です </div> </div> <divclass="accordion-box column"> <pclass="accordion">アコーディオンC</p> <divclass="accordion-content"> アコーディオンの中身です </div> </div> </div> |
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | .column{ display:flex; flex-direction:column;} .accordion-box{ justify-content:center; align-items:center; padding:05%;} .accordion-box+.accordion-box{ margin-top:20px;} .accordion{ border:1pxsolid#ccc; width:100%; text-align:left; position:relative; cursor:pointer; background-color:white; padding:8px08px3%;} .accordion::after{ content:''; width:8px; height:8px; border:0px; border-top:solid1pxblack; border-right:solid1pxblack; -ms-transform:rotate(135deg); -webkit-transform:rotate(135deg); margin-left:-6px; transform:rotate(135deg); position:absolute; top:50%; right:4%; margin-top:-5px;} .accordion-inner{ padding:30px060px0;} .accordion-content{ display:none; padding:8px08px3%; width:100%; text-align:left; background-color:#e1a948; } .heading{ padding:05%; margin-bottom:10px; } |
CSSです。
・after疑似要素で下向きのマークを作っています。
・+セレクタを使って2番目以降のアコーディオンに上方向のマージンを当てています。
jQuery
1 2 3 | $('.accordion').click(function(){ $(this).next().slideToggle(300); }); |
・accordionクラスをクリックした際に、accordionクラスの次の要素をslideToggleメソッドを使って開け閉めしています。今回は300ミリ秒(0.3秒)を引数で与えています。
デモサイト
複数開けるタイプ(最初から開いているものアリ)
「複数開けるタイプ」とほぼ同じで、開けておきたいものにopenクラスを付与しています。 jQueryは同一なので掲載していません。
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <divclass="accordion-inner"> <h3class="heading">複数開けるタイプ(最初から開いているものアリ)</h3> <divclass="accordion-box column"> <pclass="accordion">アコーディオンA</p> <divclass="accordion-content open"> アコーディオンの中身です </div> </div> <divclass="accordion-box column"> <pclass="accordion">アコーディオンB</p> <divclass="accordion-content"> アコーディオンの中身です </div> </div> <divclass="accordion-box column"> <pclass="accordion">アコーディオンC</p> <divclass="accordion-content"> アコーディオンの中身です </div> </div> </div> |
CSS
1 2 3 | .open{ display:block; } |
openクラスのcssです。
1つしか開けられないタイプ
HTMLとCSSは「複数開けられるタイプ」とほぼ同じです。
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <divclass="accordion-inner"> <h3class="heading">1つしか開けられないタイプ</h3> <divclass="accordion-box column"> <pclass="accordion-one">アコーディオンA</p> <divclass="accordion-content"> アコーディオンの中身です </div> </div> <divclass="accordion-box column"> <pclass="accordion-one">アコーディオンB</p> <divclass="accordion-content"> アコーディオンの中身です </div> </div> <divclass="accordion-box column"> <pclass="accordion-one">アコーディオンC</p> <divclass="accordion-content"> アコーディオンの中身です </div> </div> </div> |
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | .accordion-one{ border:1pxsolid#ccc; width:100%; text-align:left; position:relative; cursor:pointer; background-color:white; padding:8px08px3%;} .accordion-one::after{ content:''; width:8px; height:8px; border:0px; border-top:solid1pxblack; border-right:solid1pxblack; -ms-transform:rotate(135deg); -webkit-transform:rotate(135deg); margin-left:-6px; transform:rotate(135deg); position:absolute; top:50%; right:4%; margin-top:-5px;} |
jQuery
1 2 3 4 | $('.accordion-one').click(function(){ $(this).next().slideToggle(300); $('.accordion-one').not($(this)).next().slideUp(300); }); |
・1つしか開いていない状態にするため、notメソッドを使って「クリックしたaccordion-oneクラス」以外の「accordion-oneクラス」をslideUPメソッドで非表示にしています。
横に開くタイプ
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <divclass="accordion-inner"> <h3class="heading">横に開くタイプ</h3> <divclass="accordion-box-side row"> <pclass="accordion-side">アコーディオンA</p> <divclass="accordion-content-side"> アコーディオンの中身です </div> </div> <divclass="accordion-box-side row"> <pclass="accordion-side">アコーディオンB</p> <divclass="accordion-content-side"> アコーディオンの中身です </div> </div> <divclass="accordion-box-side row"> <pclass="accordion-side">アコーディオンC</p> <divclass="accordion-content-side"> アコーディオンの中身です </div> </div> </div> |
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | .row{ display:flex; flex-direction:row;} .accordion-side{ border:1pxsolid#ccc; width:40%; text-align:left; position:relative; cursor:pointer; background-color:white; padding:8px8px8px3%;} .accordion-side::after{ content:''; width:8px; height:8px; border:0px; border-top:solid1pxblack; border-right:solid1pxblack; -ms-transform:rotate(45deg); -webkit-transform:rotate(45deg); margin-left:-6px; transform:rotate(45deg); position:absolute; top:50%; right:4%; margin-top:-5px;} .accordion-content-side{ display:none; padding:8px8px; width:60%; text-align:center; white-space:nowrap; background-color:#e1a948; } .accordion-box-side{ justify-content:flex-start; align-items:stretch; padding:05%;} .accordion-box-side+.accordion-box-side{ margin-top:20px;} |
横向きということで多少CSSが変わっています。
・中身であるaccordion-content-sideクラスのwhite-spaceプロパティに改行をしなくなる「nowrap」を指定しています。こうしないと中身が縮んだ際にテキストが崩れて残念な表示になります。
・親要素の幅と子要素の幅を合わせて100%になるように指定。
・疑似要素のマークをrotateの数字を調整して右向きにしています。
jQuery
1 2 3 | $('.accordion-side').click(function(){ $(this).next().animate({width:'toggle'},'normal'); }); |
横向きの場合はanimateメソッドを使います。
・クリックしたaccordion-sideクラスの「次の要素のwidthプロパティ」を、’toggle’指定を使って表示/非表示で切り替えています。速度には「normal」を指定しました。
横に開くタイプ(1つしか開けられない)
HTMLとCSSは「横に開くタイプ」とほぼ同じです。
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <divclass="accordion-inner"> <h3class="heading">横に開くタイプ(1つしか開けられないタイプ)</h3> <divclass="accordion-box-side row"> <pclass="accordion-side-one">アコーディオンA</p> <divclass="accordion-content-side"> アコーディオンの中身です </div> </div> <divclass="accordion-box-side row"> <pclass="accordion-side-one">アコーディオンB</p> <divclass="accordion-content-side"> アコーディオンの中身です </div> </div> <divclass="accordion-box-side row"> <pclass="accordion-side-one">アコーディオンC</p> <divclass="accordion-content-side"> アコーディオンの中身です </div> </div> </div> |
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | .accordion-side-one{ border:1pxsolid#ccc; width:40%; text-align:left; position:relative; cursor:pointer; background-color:white; padding:8px8px8px3%;} .accordion-side-one::after{ content:''; width:8px; height:8px; border:0px; border-top:solid1pxblack; border-right:solid1pxblack; -ms-transform:rotate(45deg); -webkit-transform:rotate(45deg); margin-left:-6px; transform:rotate(45deg); position:absolute; top:50%; right:4%; margin-top:-5px;} |
jQuery
1 2 3 4 5 6 7 8 | $('.accordion-side-one').click(function(){ $(this).next().animate({ width:'toggle' },'normal'); $('.accordion-side-one').not($(this)).next().animate({ width:'hide' },'normal'); }); |
縦開きの1つしか開けられないタイプと同じく、notメソッドで「クリックしたaccordion-side-oneクラス」以外の「accordion-side-oneクラス」のwidthプロパティをanimateメソッドの’hide‘指定で非表示にしています。
カテゴリメニュー型
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | <divclass="accordion-inner"> <h3class="heading">カテゴリメニュー型</h3> <divclass="accordion-category-wrap row"> <divclass="accordion-category-box"> <pclass="accordion-category">大カテゴリA</p> <ulclass="category"> <liclass="category-item"><ahref="#">小カテゴリa</a></li> <liclass="category-item"><ahref="#">小カテゴリb</a></li> <liclass="category-item"><ahref="#">小カテゴリc</a></li> <liclass="category-item"><ahref="#">小カテゴリd</a></li> <liclass="category-item"><ahref="#">小カテゴリe</a></li> <liclass="category-item"><ahref="#">小カテゴリf</a></li> </ul> </div> <divclass="accordion-category-box"> <pclass="accordion-category">大カテゴリB</p> <ulclass="category"> <liclass="category-item"><ahref="#">小カテゴリa</a></li> <liclass="category-item"><ahref="#">小カテゴリb</a></li> <liclass="category-item"><ahref="#">小カテゴリc</a></li> <liclass="category-item"><ahref="#">小カテゴリd</a></li> <liclass="category-item"><ahref="#">小カテゴリe</a></li> <liclass="category-item"><ahref="#">小カテゴリf</a></li> </ul> </div> <divclass="accordion-category-box"> <pclass="accordion-category">大カテゴリC</p> <ulclass="category"> <liclass="category-item"><ahref="#">小カテゴリa</a></li> <liclass="category-item"><ahref="#">小カテゴリb</a></li> <liclass="category-item"><ahref="#">小カテゴリc</a></li> <liclass="category-item"><ahref="#">小カテゴリd</a></li> <liclass="category-item"><ahref="#">小カテゴリe</a></li> <liclass="category-item"><ahref="#">小カテゴリf</a></li> </ul> </div> <divclass="accordion-category-box"> <pclass="accordion-category">大カテゴリD</p> <ulclass="category"> <liclass="category-item"><ahref="#">小カテゴリa</a></li> <liclass="category-item"><ahref="#">小カテゴリb</a></li> <liclass="category-item"><ahref="#">小カテゴリc</a></li> <liclass="category-item"><ahref="#">小カテゴリd</a></li> <liclass="category-item"><ahref="#">小カテゴリe</a></li> <liclass="category-item"><ahref="#">小カテゴリf</a></li> </ul> </div> </div> </div> |
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | ul,li{ list-style:none; } .accordion-category-wrap{ justify-content:flex-start; align-items:center; flex-flow:wrap; width:100%; padding:05%; } .accordion-category-box{ width:50%; } .accordion-category{ border:1pxsolid#ccc; padding:8px; position:relative; } .accordion-category::after{ content:''; width:8px; height:8px; border:0px; border-top:solid1pxblack; border-right:solid1pxblack; -ms-transform:rotate(135deg); -webkit-transform:rotate(135deg); margin-left:-6px; transform:rotate(135deg); position:absolute; top:50%; right:4%; margin-top:-5px; } .category{ width:100%; flex-flow:wrap; justify-content:center; align-items:center; display:none; } .category-item{ background-color:azure; padding:8px; border:1pxsolid#ccc; } .category-itema{ width:100%; display:block; } |
jQuery
1 2 3 | $('.accordion-category').click(function(){ $(this).next().slideToggle(300); }); |
jQueryに関しては「複数開けるタイプ」と同様です。notメソッドを利用すれば1つしか開かなくすることもできます。
HTML5のみ/1パターン
detailsタグとsummaryタグを使います!
HTML
1 2 3 4 5 6 7 8 9 | <divclass="accordion-inner"> <h3class="heading">縦開き</h3> <details> <summary>中身の要約</summary> <pclass="details-text">中身</p> <pclass="details-text">中身</p> <pclass="details-text">中身</p> </details> </div> |
CSS
1 2 3 4 5 6 7 8 9 10 | details{ padding:10px5%; } summary{ padding:10px0; } .details-text{ padding:8px8px8px16px; background-color:#e1a948; } |
・detailsタグの子要素にsummaryタグを配置すればOKです。summaryタグと同階層にあるpタグは「detailsの内容」を示しており、メニューの中身になります。
※detailsタグとsummaryタグの本来の用途はdetailタグの内容をsummaryタグで要約することです。不適切なマークアップにならないよう内容に気を付けましょう!
CSS/2パターン
縦開き
HTML
1 2 3 4 5 6 7 8 9 10 | <divclass="accordion-inner"> <h3class="heading">縦開き</h3> <divclass="accordion-box column"> <inputtype="checkbox"id="accordion-check"> <labelclass="accordion-label"for="accordion-check">アコーディオンA</label> <divclass="accordion-content-css"> アコーディオンの中身です </div> </div> </div> |
・labelタグのfor属性を使ってinputタグとlabelタグを紐づけます。こうすることでラベルがクリックされた際にチェックが入るようになります。
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | .accordion-label{ border:1pxsolid#ccc; width:100%; text-align:left; position:relative; cursor:pointer; background-color:white; padding:8px08px3%;} .accordion-label::after{ content:''; width:8px; height:8px; border:0px; border-top:solid1pxblack; border-right:solid1pxblack; -ms-transform:rotate(135deg); -webkit-transform:rotate(135deg); margin-left:-6px; transform:rotate(135deg); position:absolute; top:50%; right:4%; margin-top:-5px;} #accordion-check{ display:none; } .accordion-content-css{ height:0; padding:0003%; width:100%; text-align:left; background-color:#e1a948; transition:all.3s; opacity:0; } #accordion-check:checked ~ .accordion-content-css{ padding:8px08px3%; height:32px; opacity:1; } |
・アコーディオンの中身である「accordion-content-css」の高さと不透明度を0にしておきます。
・「~」セレクタを使って条件分岐のようなことをしています。上のソースの場合、「#accordion-check」にチェックがついている場合、「accordion-content-css」クラスに括弧内の内容が適用されて表示されるようになります。
横開き
HTML
1 2 3 4 5 6 7 8 9 10 | <divclass="accordion-inner"> <h3class="heading">横開き</h3> <divclass="accordion-box row"> <inputtype="checkbox"id="accordion-check2"> <labelclass="accordion-label-side"for="accordion-check2">アコーディオンA</label> <divclass="accordion-content-css-side"> アコーディオンの中身です </div> </div> </div> |
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #accordion-check2{ display:none; } .accordion-label-side{ border:1pxsolid#ccc; width:50%; height:100%; text-align:left; position:relative; cursor:pointer; background-color:white; padding:8px8px8px3%;} .accordion-label-side::after{ content:''; width:8px; height:8px; border:0px; border-top:solid1pxblack; border-right:solid1pxblack; -ms-transform:rotate(45deg); -webkit-transform:rotate(45deg); margin-left:-6px; transform:rotate(45deg); position:absolute; top:50%; right:4%; margin-top:-5px;} .accordion-content-css-side{ opacity:0; padding:8px3%8px3%; width:50%; text-align:center; background-color:#e1a948; transition:all.5s; transform:translateX(-100%); z-index:-2; } #accordion-check2:checked~.accordion-content-css-side { padding:8px3%8px3%; opacity:1; transform:translateX(0); } @mediascreenand(max-width:480px){ .accordion-content-css-side{ font-size:0.8rem; } } |
・仕組みは縦開きのものと同様で、最初はアコーディオンの中身である「accordion-content-css-side」の不透明度を0にしつつ「transform:tranlateX」で左にずらしておきます。チェックボックスにチェックが入ったら透明度を1にしつつ元の位置へ戻すようにしています。
おわりに
今回は9パターンのアコーディオンメニューを作成しました。アコーディオンメニューはjQueryで作ることが多かったのですがCSSのみでもなんとかなりそうですね!
CSSのセレクタはまだ使ったことがないものが多いのでうまく使えば複雑な動きもつけられるかもしれません。いろいろ試してみたいと思います。