アコーディオンメニューの作り方[前編]

こんにちは、いすいです。

本日は Webサービス(サイトやアプリ) で、

アコーディオンメニューを作とうとしたのですが色々試行錯誤あったので、

後人のため共有いたします。

ちなみに、今回は前編です。

後編もあります。)

そもそもアコーディオンメニューとは、どんなの?

mac なら Finder(上図)、Windows なら エクスプローラー

をイメージしていただくと良いのですが、

フォルダは階層構造になっていて、クリックすると開いたり閉じたりします。

こういうのをアコーディオンメニューと言います。

Webサービスをつくるときに、こういうメニューを作りたいという時はないでしょうか。

実際、こういうメニューをサイドバーとして用意しているサイトは結構あります。

例えば、Microsoftの記事とかです。

https://learn.microsoft.com/ja-jp/azure/ai-services/openai/overview

じゃあ真似してやってみよう!となっても意外と大変。。。

僕が色々試行錯誤した結果を、

できるだけシンプルな例で3選ご紹介いたします。

やり方3選

htmlだけでやる方法

htmlだけでやる方法として試したのが、

「summary」と「detail」タグを使うものです。

基本は以下の2階層の形なのですが、

<details>
    <summary>テストA</summary>
    テストB
</details>

以下のように何階層でもいけます。

<details>
    <summary>テストA</summary>
    <details>
        <summary>テストB</summary>
        <details>
            <summary>テストC</summary>
            テストD
        <details>
    <details>
</details>

CSSで左マージンをつけてあげれば、それっぽくなります。

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <style>
        details, span {
            margin-left: 10px;
        }

        summary{
            cursor: pointer;
        }
    </style>
</head>

<body>
    <details>
        <summary>テストA</summary>
        <details>
            <summary>テストB</summary>
            <details>
                <summary>テストC</summary>
                <span>テストD</span>
            </details>
        </details>
    </details>
</body>

</html>
テストA
テストB
テストC テストD

html, css, javascriptを使う方法

css, javascript を使う方法もありまして、

javascript でクラスを書き換えることで、CSSの「height」を0から100pxにしています。

(正直 javascript で height を変えているだけです。)

その際、css の transition でアニメーションっぽくしています。

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <style>
        .list {
            transition: height 500ms;
            display: block;
            overflow: hidden;
            height: 0px;

            &.open {
                display: block;
                overflow: hidden;
                height: 100px;
            }
        }
    </style>
</head>

<body>
    <ul>
        <li>
            <button type="button" onclick="switchList('listA')">テストA</button>
            <ul id="listA" class="list">
                <li>
                    <button type="button" onclick="switchList('listB')">テストB</button>
                    <ul id="listB" class="list">
                        <li>
                            <button type="button" onclick="switchList('listC')">テストC</button>
                            <ul id="listC" class="list">
                                <li>テストD</li>
                            </ul>
                        </li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>

    <script type="text/javascript">
        function switchList(listname) {
            var list = document.getElementById(listname);

            if (list.clientHeight == 0) {
                list.classList.add("open");
            }
            else {
                list.classList.remove("open");
            }
        }
    </script>
</body>

</html>
        • テストD

まあ、どちらかというと力技のほうだとは思いますww

bootstrapを使う方法

bootstrap にはアコーディオンのライブラリが存在します。

以下のサイトを参考にしました。

https://qiita.com/yourao424/items/100e8ea5f4c01a704574

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
        crossorigin="anonymous"></script>
    <style>
        .accordion--custom .accordion-header {
            display: flex;
            /* make flex element */
            align-items: center;
            /* aligning child items */
            column-gap: 1rem;
            /* adding gap between items in row */
            padding-left: 1rem;
        }

        /* small udjustments */
        .accordion--custom .accordion-header .accordion-button {
            padding-left: 0;
            background: none;
        }

        .accordion--custom .accordion-header .accordion-button:focus {
            box-shadow: none;
        }

        .accordion--custom .accordion-header .form-check-input {
            margin-top: 0;
        }
    </style>
</head>

<body>
    <div>
        <div class="accordion accordion--custom" id="accordionCheckBox">
            <div class="accordion-item">
                <div class="accordion-header" id="accordionHeader_1">
                    <button class="accordion-button" type="button" data-bs-toggle="collapse"
                        data-bs-target="#accordionCollapse_1" aria-expanded="true" aria-controls="accordionCollapse_1">
                        テストA
                    </button>
                </div>
                <div id="accordionCollapse_1" class="accordion-collapse collapse" aria-labelledby="accordionHeader_1">
                    <div class="accordion-body">
                        <div class="accordion-header" id="accordionHeader_2">
                            <button class="accordion-button" type="button" data-bs-toggle="collapse"
                                data-bs-target="#accordionCollapse_2" aria-expanded="true"
                                aria-controls="accordionCollapse_2">
                                テストB
                            </button>
                        </div>
                        <div id="accordionCollapse_2" class="accordion-collapse collapse" aria-labelledby="accordionHeader_2">
                            <div class="accordion-body">
                                <div class="accordion-header" id="accordionHeader_3">
                                    <button class="accordion-button" type="button" data-bs-toggle="collapse"
                                        data-bs-target="#accordionCollapse_3" aria-expanded="true"
                                        aria-controls="accordionCollapse_3">
                                        テストC
                                    </button>
                                </h2>
                                <div id="accordionCollapse_3" class="accordion-collapse collapse" 
                                aria-labelledby="accordionHeader_3" data-bs-parent="#accordionCheckBox">
                                    <div class="accordion-body">
                                        テストD
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

</body>

</html>
テストD

(個人的には、bootstrapはあまり使わない主義なんですけどね、、)

まとめ

以上、アコーディオンを実装する方法3選でした。

後編もありますので、ぜひこちらも見ていただければと思います。

後編は React での実装方法です。

SNSでもご購読できます。

コメント

コメントを残す

*