【PR】を含みます。

フロントエンド

【HTML・CSS】アコーディオンメニューをHTMLとCSSのみで実装する方法

HTML・CSS アコーディオンメニューをHTMLとCSSのみで実装する方法

Webサイトでよく見かけるアコーディオンメニュー(折りたたみメニュー)。

実は、JavaScriptを使わなくてもHTMLとCSSだけで実装できることをご存知ですか?

この記事では、JavaScriptに依存しない軽量で高速なアコーディオンメニューの実装方法を詳しく解説します。

単体用から複数段対応、さらにはボタンデザインのカスタマイズまで、コピペで使えるサンプルコード付きで紹介するので、すぐに実装に取り組めます。

特に、ページの読み込み速度を重視したい方や、JavaScriptの実装が苦手な方におすすめの方法です。

アコーディオンをHTMLのみで実装する方法は以下の記事で紹介しています。

あわせて読む
CSS不要 HTMLのみでアコーディオン(開閉ボタン)を実装する方法

【CSS不要】HTMLのみでアコーディオン(開閉ボタン)を実装する方法

もくじ【サンプル】HTMLのみでアコーディオンメニューを実装【実装コード】HTMLのみでアコーディオンメニューを実装detailsタグとsummaryタグにCSS当ててデザインを調整【サンプル】CSS ...

アコーディオンをjQueryで実装する方法は以下の記事で紹介しています。

あわせて読む
jQuery アコーディオン(開閉ボタン)を実装する方法

【jQuery】アコーディオン(開閉ボタン)を実装する方法

もくじ【サンプル】jQueryでアコーディオンメニューを実装【コピペOK】jQueryを使用したアコーディオンメニューの実装コード【サンプル】jQueryでアクセシビリティ対応済みのアコーディオンメニ ...

アコーディオンをJavaScriptで実装する方法は以下の記事で紹介しています。

あわせて読む
JavaScript jQuery未使用でアコーディオン(開閉ボタン)を実装する方法

【JavaScript】jQuery未使用でアコーディオン(開閉ボタン)を実装する方法

もくじ【実装例】jQuery未使用のアコーディオンメニュー(開閉ボタン)のサンプル【コピペOK】jQuery未使用のアコーディオンメニューの実装コード【実装例】アクセシビリティ対応済みのアコーディオン ...

単体用アコーディオン(折りたたみメニュー)

【サンプル】単体用アコーディオン

【コピペOK】HTML・CSSのみで単体用アコーディオンを実装

Copyをクリックするとコピーできます。

HTML
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 -->
CSS
Copy
.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をクリックするとコピーできます。

HTML
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を固有値に変更する。

【サンプル】単体用アコーディオンの例だと以下のようになります。

HTML
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 -->
<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行目は省略)

CSS
Copy
/* 折り畳みメニューを追加する場合 */
.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をクリックするとコピーできます。

HTML
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 -->
CSS
Copy
.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をクリックするとコピーできます。

HTML
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 -->
CSS
Copy
.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をクリックするとコピーできます。

HTML
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 -->
CSS
Copy
.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箇所を下記のように変更。

CSS
Copy
.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プロパティでボタンの回転アニメーションを実現

実装時の注意点

  • 複数のアコーディオンを使用する場合は、idfor属性を固有値に変更
  • CSSセレクタの記述順序に注意(詳細度の高いセレクタを後ろに配置)

活用シーン

  • FAQページの実装
  • ナビゲーションメニューの展開
  • 設定画面のオプション表示
  • モバイル対応のコンパクトなUI

この方法を使えば、JavaScriptに依存しない軽量なアコーディオンメニューを簡単に実装できます。

アコーディオンをHTMLのみで実装する方法は以下の記事で紹介しています。

あわせて読む
CSS不要 HTMLのみでアコーディオン(開閉ボタン)を実装する方法

【CSS不要】HTMLのみでアコーディオン(開閉ボタン)を実装する方法

もくじ【サンプル】HTMLのみでアコーディオンメニューを実装【実装コード】HTMLのみでアコーディオンメニューを実装detailsタグとsummaryタグにCSS当ててデザインを調整【サンプル】CSS ...

アコーディオンをjQueryで実装する方法は以下の記事で紹介しています。

あわせて読む
jQuery アコーディオン(開閉ボタン)を実装する方法

【jQuery】アコーディオン(開閉ボタン)を実装する方法

もくじ【サンプル】jQueryでアコーディオンメニューを実装【コピペOK】jQueryを使用したアコーディオンメニューの実装コード【サンプル】jQueryでアクセシビリティ対応済みのアコーディオンメニ ...

アコーディオンをJavaScriptで実装する方法は以下の記事で紹介しています。

あわせて読む
JavaScript jQuery未使用でアコーディオン(開閉ボタン)を実装する方法

【JavaScript】jQuery未使用でアコーディオン(開閉ボタン)を実装する方法

もくじ【実装例】jQuery未使用のアコーディオンメニュー(開閉ボタン)のサンプル【コピペOK】jQuery未使用のアコーディオンメニューの実装コード【実装例】アクセシビリティ対応済みのアコーディオン ...

-フロントエンド
-,