home
twitter
ページトップへ
目次
  • 「アコーディオンメニュー」とは何か
  • 「details」と「summary」要素を使った簡単な「アコーディオンメニュー」の作り方!
  • 「JavaScript」を使ってカスタマイズ可能な「アコーディオンメニュー」を作る方法!
  • 「HTML」ファイル!
  • 「CSS」ファイル!
  • 「JavaScript」ファイル!
  • 「display」の切り替えではなく「height」を切り替える
  • 2つ目をクリックしたら、1つ目を閉じる処理を追加!
  • どちらを使うべき?
  • 「details」と「summary」
  • 「JavaScript」を使った方法
  • まとめ!
about
categories
page
archive
皇帝ペンギンブログ

2024/12/22 (更新日:2024/12/23)

【JavaScript】「アコーディオンメニュー」をライブラリなしで作る方法【アニメーションつき】

Categories > JavaScriptの入門編
こんばんは!初めましての方は初めまして!
しゅーた(@chibasyuta)です!

この記事では「アコーディオンメニュー」の作り方を解説します。

具体的にはライブラリを使わずに「JavaScript」だけでアニメーションつきのアコーディオンメニューを作る方法をご紹介します。

「jQuery」などのライブラリは使わず、そのままの「JavaScript」だけを使って実装することで、「JavaScript」の勉強になりますし、カスタマイズしやすい内容となるかと思います。

また、簡易的な「アコーディオンメニュー」なら、HTML要素だけで作ることができるので、そちらの方法もあわせて解説します。

この記事の内容!

  • 「アコーディオンメニュー」とは何か
  • 「details」と「summary」を使った簡単な実装
  • 「JavaScript」を使った実装
また、下の動画でも「アコーディオンメニュー」の作り方について詳しく解説しているので、一緒に実際にコードを書きながら学びたい方はこちらをどうぞ!

それでは内容へ入ります!

目次
非表示
  • 「アコーディオンメニュー」とは何か
  • 「details」と「summary」要素を使った簡単な「アコーディオンメニュー」の作り方!
  • 「JavaScript」を使ってカスタマイズ可能な「アコーディオンメニュー」を作る方法!
  • 「HTML」ファイル!
  • 「CSS」ファイル!
  • 「JavaScript」ファイル!
  • 「display」の切り替えではなく「height」を切り替える
  • 2つ目をクリックしたら、1つ目を閉じる処理を追加!
  • どちらを使うべき?
  • 「details」と「summary」
  • 「JavaScript」を使った方法
  • まとめ!

「アコーディオンメニュー」とは何か

https://chibasyuta.org/wp-content/uploads/2024/12/accordion-menu_new.mp4
「アコーディオンメニュー」とは、クリックするとその内容の表示・非表示が切り替わるようなタイプのメニューのことを指します。

主に多くの情報をコンパクトに整理して表示するために使われます。

名前の由来は、初めは隠れている部分が、クリックと同時に表示されるのが、楽器のアコーディオンのようなので、このような名前で呼ばれています。広がったり縮んだりする動きが似ていますよね。

具体例!

FAQ、商品の詳細説明など、多くの情報を扱う場面で特に役立ちます。

「details」と「summary」要素を使った簡単な「アコーディオンメニュー」の作り方!

https://chibasyuta.org/wp-content/uploads/2024/12/accordion-details-summary_new.mp4

本格的な「アコーディオンメニュー」の前に、HTML要素だけで作れる簡単な「アコーディオンメニュー」の作り方から解説します!

<div class="container">
    <details>
        <summary>項目</summary>
        <p>えーっとまあ、内容です。</p>
    </details>
    <details>
        <summary>項目</summary>
        <p>えーっとまあ、内容です。</p>
    </details>
    <details>
        <summary>項目</summary>
        <p>えーっとまあ、内容です。</p>
    </details>
</div>
.container {
    width: 700px;
    margin: 160px auto;
}
details {
    font-size: 50px;
    margin-bottom: 10px;
    cursor: pointer;
}

このように「details」と「summary」要素を使うと、「JavaScript」を使わずとも「アコーディオンメニュー」が作れます。

「details」要素で本文を含めた全体を囲います。

そして、そしてその本文の内容を要約したものや、項目名を「summary」要素で囲えばできあがりです!「summary」要素は非表示の際に表示するテキストを囲います。

デフォルトでブラウザが表示・非表示をクリックで切り替えられるようにしてくれます。

簡単な「アコーディオンメニュー」なら、この方法でサクッと作れますね。

ですが、アニメーションを付けたりとか、そういった細かい調節がしたい場合は「JavaScript」を使った実装が必要になります。

「JavaScript」を使ってカスタマイズ可能な「アコーディオンメニュー」を作る方法!

https://chibasyuta.org/wp-content/uploads/2024/12/accordion-menu_new.mp4

このようにアニメーションをつけるなど、カスタマイズ性が高い洗練された「アコーディオンメニュー」を作るには「JavaScript」を使えば実装できます!

具体的には、パッと表示・非表示が切り替わるのではなく、アニメーションさせる感じにします。アニメーションがあった方がアコーディオンっぽいです。

では、その方法をまとめますね!

「HTML」ファイル!

<div class="container">
    <dl>
        <div class="box">
            <dt>項目</dt>
            <dd>内容です。内容です。内容です。内容です。内容です。内容です。内容です。</dd>
        </div>
        <div class="box">
            <dt>項目</dt>
            <dd>内容です。内容です。内容です。内容です。内容です。内容です。内容です。</dd>
        </div>
        <div class="box">
            <dt>項目</dt>
            <dd>内容です。内容です。内容です。内容です。内容です。内容です。内容です。</dd>
        </div>
        <div class="box">
            <dt>項目</dt>
            <dd>内容です。内容です。内容です。内容です。内容です。内容です。内容です。</dd>
        </div>
        <div class="box">
            <dt>項目</dt>
            <dd>内容です。内容です。内容です。内容です。内容です。内容です。内容です。</dd>
        </div>
        <div class="box">
            <dt>項目</dt>
            <dd>内容です。内容です。内容です。内容です。内容です。内容です。内容です。</dd>
        </div>
    </dl>
</div>

「HTML」ファイルはこんな感じで、「dl」「dt」「dd」要素を使って説明付きのリストを作ります。

「CSS」ファイル!

.container {
    width: 700px;
    margin: 80px auto;
}
.box {
    margin-bottom: 30px;
}
dt {
    background-color: #ddd;
    padding: 16px 40px;
    display: flex;
    justify-content: space-between;
    font-size: 30px;
    margin-bottom: 4px;
}
dt::after {
    content: "+";
}
.box.show dt::after {
    content: "ー";
}
dd {
    height: 0px;
    overflow: hidden;
    transition-duration: 0.4s;
    font-size: 30px;
}

「dd」要素の「height」は「0px」にしてください。

そして「JavaScript」から「show」というクラスを、つけたり外したりすることで、「+」と「-」を切り替えています。

あとは「CSS」ファイルにお好みでいろいろ設定してください。

「JavaScript」ファイル!

let dts = document.querySelectorAll('dt');

dts.forEach( (dt) => {
    dt.addEventListener('click', () => {
       
        dt.parentElement.classList.toggle('show');

        const content = dt.nextElementSibling;
        const isOpen = content.offsetHeight > 0;
        if ( isOpen ) {
            content.style.height = '0px';
        } else {
            content.style.height = `${content.scrollHeight}px`;
        }
    });
} );

後は 「JavaScript」で「アコーディオンメニュー」の動き部分を作ればOKです!

まず、全ての「dt要素」を「document.querySelectorAll(‘dt’)」で取得します。

そして、それらに「forEach」で一つ一つ処理を加えていきます。

具体的には「addEventListener」で「click」したときの処理を追加します。

今回はクリックした「dt」要素の親要素の「.box」クラスがついた「div」要素に「show」というクラスをつけたり外したりすることで、非表示の時の「+」アイコンと、表示の時の「-」アイコンを切り替えます。

そして、「dt.nextElementSibling;」でクリックされた「dl」要素の次の兄弟要素を取得して「content」で扱えるようにします。

さらに「isOpen」という変数で「メニュー」が表示モードなのか非表示モードなのかを管理ます。

具体的には「content.offsetHeight > 0;」ですね。「content」の高さが0よりも大きければ、表示されていると解釈できます。「offsetHeight」で要素の現在の高さが取得できます。

そして、クリックされた際に「内容が非表示」であれば「content.style.height = `${content.scrollHeight}px`」として、「content」に高さを指定してあげればOKです。「content.scrollHeight」で要素の本来の高さが取得できます。(画面に表示されているかではない純粋な高さが取れます。)

クリックされた際に「内容が表示」されているのであれば、「content.style.height = `0px`;」として、高さを無くしてあげればOKです。

「display」の切り替えではなく「height」を切り替える

アニメーションさせるためには「display」の切り替えではなく「height」を切り替えてください。

「display」を「block」と「none」で切り替えると、それらは離散値であるため、アニメーションさせることができません。中間というのがないからです。

なので「height」を切り替えてください。

2つ目をクリックしたら、1つ目を閉じる処理を追加!

let dts = document.querySelectorAll('dt');

dts.forEach( (dt) => {
    dt.addEventListener('click', () => {

        // 追加部分
        dts.forEach( (dt) => {
            dt.nextElementSibling.style.height = '0px';
            dt.parentElement.classList.remove('show');
        } );

        const content = dt.nextElementSibling;
        const isOpen = content.offsetHeight > 0;
        if ( isOpen ) {
            content.style.height = '0px';
        } else {
            content.style.height = `${content.scrollHeight}px`;
            // toggleからaddに変更してここに移動
            dt.parentElement.classList.add('show');
        }
    });
} );

このように、コードを追加することで、複数のメニューが同時に表示されないようにすることができます。

なるほど!メニューが開きすぎて長くなってしまうのを防げるね!

どちらを使うべき?

簡単な「details」と「summary」を使った実装と、「JavaScript」を使った実装の使い分け方にも触れておくね!

「details」と「summary」

おすすめの場合: 時間をかけず簡単に作りたいとき。

用途: ドキュメントやFAQのような簡単なUIで十分な場合。

「JavaScript」を使った方法

おすすめの場合: デザインや挙動を細かく調整したいとき。

まとめ!

簡単な方法として「details」と「summary」を使うのも良いですが、デザインや動きを自由にカスタマイズしたい場合は「JavaScript」を使った実装を検討してみてください。

両者を使い分けることで、プロジェクトに合った最適な「アコーディオンメニュー」を作ることができます!

また、下の動画でも「アコーディオンメニュー」の作り方について詳しく解説しているので、一緒に実際にコードを書きながら学びたい方はこちらをどうぞ!

それでは、こんな感じでこの記事を終わります!

またね!

自分のロゴ!

皇帝ペンギン

全力で、書きます。
少しでもお役に立てたら幸いです。
楽しんで読んで下さい 。-_- 。
よろしくお願いします!

x(旧twitter) youtube
Categories
  • トップへ
  • ITパスポート (1)
  • programming (168)
    • CSSのアニメーション編 (26)
    • CSSのグリッドレイアウト編 (1)
    • CSSのセレクター編 (58)
    • CSSのフレックスボックス編 (1)
    • CSSのメディアクエリー編 (7)
    • CSSの基本編 (34)
    • HTMLのformタグ編 (1)
    • HTMLの基本編 (3)
    • JavaScriptの入門編 (30)
    • JavaScriptの基本編 (5)
    • Web制作をする環境を整えよう! (1)
  • Uncategorized (23)
  • VScode (1)
  • おすすめ商品! (1)
  • クラロワ (2)
  • マーケティング (17)
  • 大学生活 (7)
  • 心理学 (9)
  • 映画 (1)
  • 法学 (4)
  • 経済学 (4)
  • 読書 (7)
Pages
  • プライバシーポリシー
  • 免責事項
  • プロフィール
Archive
  • 2025年3月 (1)
  • 2025年1月 (9)
  • 2024年12月 (13)
  • 2024年11月 (5)
  • 2024年10月 (10)
  • 2024年9月 (15)
  • 2024年8月 (5)
  • 2024年7月 (6)
  • 2024年6月 (5)
  • 2024年5月 (10)
  • 2024年4月 (24)
  • 2024年3月 (11)
  • 2024年2月 (6)
  • 2024年1月 (10)
  • 2023年12月 (4)
  • 2023年11月 (3)
  • 2023年10月 (2)
  • 2023年9月 (3)
  • 2023年8月 (6)
  • 2023年7月 (3)
  • 2023年6月 (8)
  • 2023年5月 (2)
  • 2023年3月 (1)
  • 2023年2月 (1)
  • 2022年10月 (2)
  • 2022年9月 (2)
  • 2022年8月 (8)
  • 2022年7月 (2)
  • 2022年6月 (6)
  • 2022年5月 (9)
  • 2022年4月 (2)
  • 2022年2月 (4)
  • 2021年12月 (1)
  • 2021年11月 (4)
  • 2021年10月 (8)
  • 2021年9月 (14)
  • 2021年8月 (6)
  • 2021年6月 (1)
  • 2021年5月 (2)
  • 2021年4月 (1)
  • 2021年3月 (1)
  • 2021年2月 (2)
  • 2020年10月 (1)
  • 2020年7月 (1)
  • 2020年4月 (1)
  • 2020年1月 (1)
  • 2019年12月 (2)
© Copyright Syuta Chiba, 2019 All Rights Reserved.