Webサイトでよく見かけるアコーディオンメニュー(折りたたみメニュー)。
実は、JavaScriptを使わなくてもHTMLとCSSだけで実装できることをご存知ですか?
この記事では、JavaScriptに依存しない軽量で高速なアコーディオンメニューの実装方法を詳しく解説します。
単体用から複数段対応、さらにはボタンデザインのカスタマイズまで、コピペで使えるサンプルコード付きで紹介するので、すぐに実装に取り組めます。
特に、ページの読み込み速度を重視したい方や、JavaScriptの実装が苦手な方におすすめの方法です。
アコーディオンをHTMLのみで実装する方法は以下の記事で紹介しています。
-
【CSS不要】HTMLのみでアコーディオン(開閉ボタン)を実装する方法
もくじ【サンプル】HTMLのみでアコーディオンメニューを実装【実装コード】HTMLのみでアコーディオンメニューを実装detailsタグとsummaryタグにCSS当ててデザインを調整【サンプル】CSS ...
アコーディオンをjQueryで実装する方法は以下の記事で紹介しています。
-
【jQuery】アコーディオン(開閉ボタン)を実装する方法
もくじ【サンプル】jQueryでアコーディオンメニューを実装【コピペOK】jQueryを使用したアコーディオンメニューの実装コード【サンプル】jQueryでアクセシビリティ対応済みのアコーディオンメニ ...
アコーディオンをJavaScriptで実装する方法は以下の記事で紹介しています。
-
【JavaScript】jQuery未使用でアコーディオン(開閉ボタン)を実装する方法
もくじ【実装例】jQuery未使用のアコーディオンメニュー(開閉ボタン)のサンプル【コピペOK】jQuery未使用のアコーディオンメニューの実装コード【実装例】アクセシビリティ対応済みのアコーディオン ...
単体用アコーディオン(折りたたみメニュー)
【サンプル】単体用アコーディオン
【コピペOK】HTML・CSSのみで単体用アコーディオンを実装
Copyをクリックするとコピーできます。
<div class="menu-box">
<input id="check-box" type="checkbox">
<label class="menu-label-title" for="check-box">
<span class="menu-title">Q.クリック</span>
<span></span>
<span></span>
</label><!-- .menu-label-title -->
<div class="menu-text">A.テキスト</div>
</div><!-- .menu-box -->
.menu-box {
border: solid 1px #c0c0c0;
}
.menu-box .menu-label-title {
display: block;
padding: 20px 25px;
cursor: pointer;
position: relative;
}
.menu-box .menu-title {
display: block;
padding-right: 50px;
}
.menu-box .menu-label-title span:nth-child(2),
.menu-box .menu-label-title span:nth-child(3) {
display: block;
width: 16px;
border-bottom: solid 1px #c0c0c0;
position: absolute;
top: 50%;
right: 25px;
transform: translateY(-50%);
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
}
.menu-box .menu-label-title span:nth-child(2) {
transform: rotate(45deg);
right: 36px;
}
.menu-box .menu-label-title span:nth-child(3) {
transform: rotate(-45deg);
}
.menu-box .menu-text {
display: none;
padding: 20px 0;
margin: 0 25px;
border-top: dotted 1px #c0c0c0;
}
/* 折り畳みメニューを追加する場合 */
.menu-box #check-box {
display: none;
}
.menu-box #check-box:checked ~ .menu-text {
display: block;
}
.menu-box #check-box:checked ~ .menu-label-title span:nth-child(2) {
transform: rotate(-45deg);
}
.menu-box #check-box:checked ~ .menu-label-title span:nth-child(3) {
transform: rotate(45deg);
}
/* ここまで */
単体用アコーディオンを複数利用する方法
Copyをクリックするとコピーできます。
<div class="menu-box">
<input id="check-box" type="checkbox">
<label class="menu-label-title" for="check-box">
<span class="menu-title">Q.クリック</span>
<span></span>
<span></span>
</label><!-- .menu-label-title -->
<div class="menu-text">A.テキスト</div>
</div><!-- .menu-box -->
上記のコードを必要な数任意の場所に貼り付け。
貼り付けた2つ目以降のid="check-box"
とfor="check-box"
のcheck-box
を固有値に変更する。
【サンプル】単体用アコーディオンの例だと以下のようになります。
<div class="menu-box">
<input id="check-box" type="checkbox">
<label class="menu-label-title" for="check-box">
<span class="menu-title">Q.クリック</span>
<span></span>
<span></span>
</label><!-- .menu-label-title -->
<div class="menu-text">A.テキスト</div>
</div><!-- .menu-box -->
<div class="menu-box">
<input id="check-box2" type="checkbox">
<label class="menu-label-title" for="check-box2">
<span class="menu-title">Q.クリック</span>
<span></span>
<span></span>
</label><!-- .menu-label-title -->
<div class="menu-text">A.テキスト</div>
</div><!-- .menu-box -->
最後に、CSSの46行目「/* 折り畳みメニューを追加する場合 */」から
62行目「/* ここまで */」のセレクタを変更。
今回のサンプルの例だと下記のようになります。(1~45行目は省略)
/* 折り畳みメニューを追加する場合 */
.menu-box #check-box,
.menu-box #check-box2 {
display: none;
}
.menu-box #check-box:checked ~ .menu-text,
.menu-box #check-box2:checked ~ .menu-text {
display: block;
}
.menu-box #check-box:checked ~ .menu-label-title span:nth-child(2),
.menu-box #check-box2:checked ~ .menu-label-title span:nth-child(2) {
transform: rotate(-45deg);
}
.menu-box #check-box:checked ~ .menu-label-title span:nth-child(3),
.menu-box #check-box2:checked ~ .menu-label-title span:nth-child(3) {
transform: rotate(45deg);
}
/* ここまで */
2段のアコーディオン(折りたたみメニュー)
【サンプル】2段のアコーディオン
【コピペOK】HTML・CSSのみで2段のアコーディオンを実装
Copyをクリックするとコピーできます。
<div class="double-menu-box">
<div class="menus-box">
<input id="double-check-box" type="checkbox">
<label class="menu-label-title" for="double-check-box">
<span class="menu-title">Q.クリック</span>
<span></span>
<span></span>
</label><!-- .menu-label-title -->
<div class="menu-text">A.テキスト</div>
</div><!-- .menus-box -->
<div class="menus-box">
<input id="double-check-box2" type="checkbox">
<label class="menu-label-title" for="double-check-box2">
<span class="menu-title">Q.クリック</span>
<span></span>
<span></span>
</label><!-- .menu-label-title -->
<div class="menu-text">A.テキスト</div>
</div><!-- .menus-box -->
</div><!-- .double-menu-box -->
.double-menu-box {
border: solid 1px #c0c0c0;
}
.double-menu-box .menus-box {
border-top: dashed 1px #c0c0c0;
}
.double-menu-box .menus-box:first-child {
border-top: none;
}
.double-menu-box .menu-label-title {
display: block;
padding: 20px 25px;
cursor: pointer;
position: relative;
}
.double-menu-box .menu-title {
display: block;
padding-right: 50px;
}
.double-menu-box .menu-label-title span:nth-child(2),
.double-menu-box .menu-label-title span:nth-child(3) {
display: block;
width: 16px;
border-bottom: solid 1px #c0c0c0;
position: absolute;
top: 50%;
right: 25px;
transform: translateY(-50%);
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
}
.double-menu-box .menu-label-title span:nth-child(2) {
transform: rotate(45deg);
right: 36px;
}
.double-menu-box .menu-label-title span:nth-child(3) {
transform: rotate(-45deg);
}
.double-menu-box .menu-text {
display: none;
padding: 20px 0;
margin: 0 25px;
border-top: dotted 1px #c0c0c0;
}
.double-menu-box .menus-box #double-check-box,
.double-menu-box .menus-box #double-check-box2 {
display: none;
}
.double-menu-box .menus-box #double-check-box:checked ~ .menu-text,
.double-menu-box .menus-box #double-check-box2:checked ~ .menu-text {
display: block;
}
.double-menu-box .menus-box #double-check-box:checked ~ .menu-label-title span:nth-child(2),
.double-menu-box .menus-box #double-check-box2:checked ~ .menu-label-title span:nth-child(2) {
transform: rotate(-45deg);
}
.double-menu-box .menus-box #double-check-box:checked ~ .menu-label-title span:nth-child(3),
.double-menu-box .menus-box #double-check-box2:checked ~ .menu-label-title span:nth-child(3) {
transform: rotate(45deg);
}
3段以上のアコーディオン(折りたたみメニュー)
3段以上のアコーディオン
【コピペOK】HTML・CSSのみで3段以上のアコーディオンを実装
Copyをクリックするとコピーできます。
<div class="triple-menu-box">
<div class="menus-box">
<input id="triple-check-box" type="checkbox">
<label class="menu-label-title" for="triple-check-box">
<span class="menu-title">Q.クリック</span>
<span></span>
<span></span>
</label><!-- .menu-label-title -->
<div class="menu-text">A.テキスト</div>
</div><!-- .menus-box -->
<div class="menus-box">
<input id="triple-check-box2" type="checkbox">
<label class="menu-label-title" for="triple-check-box2">
<span class="menu-title">Q.クリック</span>
<span></span>
<span></span>
</label><!-- .menu-label-title -->
<div class="menu-text">A.テキスト</div>
</div><!-- .menus-box -->
<div class="menus-box">
<input id="triple-check-box3" type="checkbox">
<label class="menu-label-title" for="triple-check-box3">
<span class="menu-title">Q.クリック</span>
<span></span>
<span></span>
</label><!-- .menu-label-title -->
<div class="menu-text">A.テキスト</div>
</div><!-- .menus-box -->
<!-- 折り畳みメニューを追加する場合はこの下に追加 -->
</div><!-- .triple-menu-box -->
.triple-menu-box {
border: solid 1px #c0c0c0;
}
.triple-menu-box .menus-box {
border-top: dashed 1px #c0c0c0;
}
.triple-menu-box .menus-box:first-child {
border-top: none;
}
.triple-menu-box .menu-label-title {
display: block;
padding: 20px 25px;
cursor: pointer;
position: relative;
}
.triple-menu-box .menu-title {
display: block;
padding-right: 50px;
}
.triple-menu-box .menu-label-title span:nth-child(2),
.triple-menu-box .menu-label-title span:nth-child(3) {
display: block;
width: 16px;
border-bottom: solid 1px #c0c0c0;
position: absolute;
top: 50%;
right: 25px;
transform: translateY(-50%);
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
}
.triple-menu-box .menu-label-title span:nth-child(2) {
transform: rotate(45deg);
right: 36px;
}
.triple-menu-box .menu-label-title span:nth-child(3) {
transform: rotate(-45deg);
}
.triple-menu-box .menu-text {
display: none;
padding: 20px 0;
margin: 0 25px;
border-top: dotted 1px #c0c0c0;
}
/* 折り畳みメニューを追加する場合 */
.triple-menu-box .menus-box #triple-check-box,
.triple-menu-box .menus-box #triple-check-box2,
.triple-menu-box .menus-box #triple-check-box3 {
display: none;
}
.triple-menu-box .menus-box #triple-check-box:checked ~ .menu-text,
.triple-menu-box .menus-box #triple-check-box2:checked ~ .menu-text,
.triple-menu-box .menus-box #triple-check-box3:checked ~ .menu-text {
display: block;
}
.triple-menu-box .menus-box #triple-check-box:checked ~ .menu-label-title span:nth-child(2),
.triple-menu-box .menus-box #triple-check-box2:checked ~ .menu-label-title span:nth-child(2),
.triple-menu-box .menus-box #triple-check-box3:checked ~ .menu-label-title span:nth-child(2) {
transform: rotate(-45deg);
}
.triple-menu-box .menus-box #triple-check-box:checked ~ .menu-label-title span:nth-child(3),
.triple-menu-box .menus-box #triple-check-box2:checked ~ .menu-label-title span:nth-child(3),
.triple-menu-box .menus-box #triple-check-box3:checked ~ .menu-label-title span:nth-child(3) {
transform: rotate(45deg);
}
/* ここまで */
ボタンを「+」と「-」に変更する方法
【サンプル】ボタンを「+」と「-」に変更する
【コピペOK】ボタンを「+」と「-」に変更する
Copyをクリックするとコピーできます。
<div class="menu-box">
<input id="check-box" type="checkbox">
<label class="menu-label-title" for="check-box">
<span class="menu-title">Q.クリック</span>
<span></span>
<span></span>
</label><!-- .menu-label-title -->
<div class="menu-text">A.テキスト</div>
</div><!-- .menu-box -->
.menu-box {
border: solid 1px #c0c0c0;
}
.menu-box .menu-label-title {
display: block;
padding: 20px 25px;
cursor: pointer;
position: relative;
}
.menu-box .menu-title {
display: block;
padding-right: 50px;
}
.menu-box .menu-label-title span:nth-child(2),
.menu-box .menu-label-title span:nth-child(3) {
display: block;
width: 16px;
border-bottom: solid 1px #c0c0c0;
position: absolute;
top: 50%;
right: 25px;
transform: translateY(-50%);
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
}
.menu-box .menu-label-title span:nth-child(2) {
transform: rotate(45deg);
right: 36px;
}
.menu-box .menu-label-title span:nth-child(3) {
transform: rotate(-45deg);
}
.menu-box .menu-text {
display: none;
padding: 20px 0;
margin: 0 25px;
border-top: dotted 1px #c0c0c0;
}
/* 折り畳みメニューを追加する場合 */
.menu-box #check-box {
display: none;
}
.menu-box #check-box:checked ~ .menu-text {
display: block;
}
.menu-box #check-box:checked ~ .menu-label-title span:nth-child(2) {
transform: rotate(-45deg);
}
.menu-box #check-box:checked ~ .menu-label-title span:nth-child(3) {
transform: rotate(45deg);
}
/* ここまで */
上記のCSSの
30~33行目
35~37行目
55~57行目
59~61行目の4箇所を下記のように変更。
.menu-box .menu-label-title span:nth-child(2) {
transform: rotate(90deg) !important;
right: 25px !important;
}
.menu-box .menu-label-title span:nth-child(3) {
transform: rotate(0deg) !important;
}
.menu-box #check-box:checked ~ .menu-label-title span:nth-child(2) {
display: none;
}
.menu-box #check-box:checked ~ .menu-label-title span:nth-child(3) {
transform: rotate(0deg);
}
まとめ
HTMLとCSSのみでアコーディオンメニューを実装する方法を紹介しました。
実装のポイント
- チェックボックスとlabel要素の組み合わせでJavaScript不要の実装が可能
- CSSの:checked疑似クラスで開閉状態を制御
transform
プロパティでボタンの回転アニメーションを実現
実装時の注意点
- 複数のアコーディオンを使用する場合は、
id
とfor
属性を固有値に変更 - CSSセレクタの記述順序に注意(詳細度の高いセレクタを後ろに配置)
活用シーン
- FAQページの実装
- ナビゲーションメニューの展開
- 設定画面のオプション表示
- モバイル対応のコンパクトなUI
この方法を使えば、JavaScriptに依存しない軽量なアコーディオンメニューを簡単に実装できます。
アコーディオンをHTMLのみで実装する方法は以下の記事で紹介しています。
-
【CSS不要】HTMLのみでアコーディオン(開閉ボタン)を実装する方法
もくじ【サンプル】HTMLのみでアコーディオンメニューを実装【実装コード】HTMLのみでアコーディオンメニューを実装detailsタグとsummaryタグにCSS当ててデザインを調整【サンプル】CSS ...
アコーディオンをjQueryで実装する方法は以下の記事で紹介しています。
-
【jQuery】アコーディオン(開閉ボタン)を実装する方法
もくじ【サンプル】jQueryでアコーディオンメニューを実装【コピペOK】jQueryを使用したアコーディオンメニューの実装コード【サンプル】jQueryでアクセシビリティ対応済みのアコーディオンメニ ...
アコーディオンをJavaScriptで実装する方法は以下の記事で紹介しています。
-
【JavaScript】jQuery未使用でアコーディオン(開閉ボタン)を実装する方法
もくじ【実装例】jQuery未使用のアコーディオンメニュー(開閉ボタン)のサンプル【コピペOK】jQuery未使用のアコーディオンメニューの実装コード【実装例】アクセシビリティ対応済みのアコーディオン ...