【HTML&CSSのみ vs jQurey使用】アコーディオンを作る方法【比較】

accordion HTMLコーダー
メニューなどでアコーディオンを作りたいけどどうやって作ればいいんだろう?
二つの作り方があるので、実際に作りながら解説させていただきます。

jQueryを利用してアコーディオンを作る

jQueryを使用したやり方なので、まずはjQueryを読み込みます。下記はjQueryのファイルをダウンロードしてきて、headタグ内で読み込んでおく例です。

HTML

<script src="js/jquery-3.4.1.min.js"></script>

次にHTML内に親要素と子要素を設定し、CSSでデザインを設定します。

HTML

<div class="parent">HTML</div>
<div class="child">
    <ul>
        <li>サイトの作り方</li>
        <li>HTMLの勉強方法</li>
        <li>参考になる書籍</li>
    </ul>
</div>

CSS

ul {
    list-style: none;
    padding: 0px;
    margin: 0px;
}

.parent {
    background-color: aqua;
    width: 300px;
    padding: 5px;
    cursor: pointer;
}

.child {
    background-color: aquamarine;
    width: 300px;
    padding: 5px;
}

accordion

次にjQeuryでメニューの開閉部分を実装します。非常に簡単です。

JavaScript

$('.parent').click(function(){
    $('.child').slideToggle();
});

これで以下の画像のような動きになります。
accordion

解説

要点を開設していきます。まず親となる要素にはclassとidにparentを指定しています。

マウスカーソルが合わさった時にクリック可能なことがわかるように「cursor: pointer;」を指定しています。

次に親要素がクリックされた際に表示される子要素にはclassとidにchildを指定しています。

こちらがアコーディオン部分として開かれたり閉じたりされる部分です。

JavaScript(jQuery)ではclass=parentがクリックされた際にclass=childが開閉される指定になります。

複数の要素

今回は一つの開閉要素なのでこちらでうまく動いていますが、以下の様に二つ以上メニューがある際にはうまく動きません。
accordion

この場合では以下のようにJavaScript部分を修正します。
JavaScript

$('.parent').click(function(){
    $(this).next().slideToggle();
});

$(this)とはクリックされたclassのこと、.next()はその次の要素という意味です。

HTML

<div class="parent">HTML</div>
<div class="child">

このようにparentの次にがchildな為うまく動いていますが、この間に何か別のタグをいれてしまうとそれが.next()の対象になってしまうのでご注意ください。

その場合でも.next().next()と二回続けることで二個先の要素を指定することも可能です。

以上がjQueryを利用したアコーディオンの実装方法でした。

HTML&CSSのみでアコーディオンを作る

続いてjQueryを利用せずにアコーディオンを実装する方法を見ていきましょう。まずhead内でjQueryのファイルを読み込む必要はありません。

最初にすべて載せて、後から解説します。

HTML

<div class="wrapper">
    <label for="chk1">HTML</label>
    <input type="checkbox" id="chk1" class="chk" />
    <div class="child">
        <ul>
            <li>サイトの作り方</li>
            <li>HTMLの勉強方法</li>
            <li>参考になる書籍</li>
        </ul>
    </div>
    <label for="chk2">CSS</label>
    <input type="checkbox" id="chk2" class="chk" />
    <div class="child">
        <ul>
            <li>色の変え方</li>
            <li>文字サイズの変更方法</li>
            <li>CSSの書き方</li>
        </ul>
    </div>
</div>

CSS

ul {
    list-style: none;
    padding: 0px;
    margin: 0px;
}

label {
    display: block;
    background-color: aqua;
    padding: 5px;
    cursor: pointer;
}

.wrapper {
    width: 300px;
}

.child {
    background-color: aquamarine;
    transition: 0.5s;
    height: auto;
    padding: 5px;
}

.chk {
    display: none;
}

.chk:checked + .child {
    overflow: hidden;
    height: 0px;
    padding: 0px;
}

解説

非表示にしたチェックボックスを隠し要素として配置し、そのチェックボックスのlabel要素をメニューの親要素に見立てています。

またチェックボックスの内容を子要素にしていることで、チェックされたボックスの子要素のみ表示非表示を切り替えるスタイルです。

labelは幅が文字の長さで決まってしまい、widthの指定ができません。なので「display: block;」も合わせて記載するとwidthの指定が利くようになります。

.chk:checked + .child

一番理解が難しいとするとここかと思います。

要はclass=chkがクリックされた際に、class=childに追加で以下の指定を行うという形です。

この例では最初は表示、クリックで閉まる開くを繰り返しですが、入れ替えれば最初に閉じておくようにすることも可能です。

どちらのやり方がおすすめか?

正直、どちらでもほぼ同じ結果が得られるので、後は好みの問題になってきてしまうと思います。

CSSのみのメリット

昔はアニメーションと言えばjQuery一択だったような気がしますが、CSSのみでもここまでできるようになったんですね。

確かにjQueryのファイルを読み込む必要がないので、もし現状でjQueryを利用していないのであれば読み込みは早くなる可能性があるというメリットがありそうです。

JSのメリット

CSS方式の気になる点としては意味のないチェックボックスがソースの中に混じるので、混乱の元になるといえばなるような気もします。

HTMLの中には一切余計なものは書かない、アニメーションなどの要素はすべてCSSとJSに分離するという点においてはjQuery方式に利点がある気がします。

CSSを書く量もjQueryを利用した方が少なくシンプルに済みますね。

現状で既にjQueryを利用しているようであればそちらを、利用していない場合はCSSのみでの実装を試してみてはいかがでしょうか。