detailsの開閉にアニメーションを追加する

detailsを使ったアコーディオンの実装が度々あるので、JavaScriptを使った開閉時のアニメーションの実装をメモしておきます。

サンプルコード

HTMLはアコーディオンと見出し、パネルの3つにJavaScript用のclassを付与します。

<details class="accordion js-accordion">
  <summary class="accordion_head js-accordion-head">アコーディオンの見出し</summary>
  <div class="accordion_body js-accordion-body">
    <div class="accordion_inner">
      <p>アコーディオンの内容</p>
    </div>
  </div>
</details>

アコーディオンのパネル部分にアニメーション用のスタイルを設定します。

.accordion_body {
  overflow: hidden;
}

最後にJavaScriptです。
アニメーション部分はWeb Animations APIを使っていますが、詳しくは以前に記事を投稿していますのでそちらをご確認ください。

document.addEventListener('DOMContentLoaded', () => {
  const $accordions = document.querySelectorAll('.js-accordion');
  const accordionSlideOptions = {
    duration: 500,
    easing: "ease"
  }

  $accordions.forEach($accordion => {
    const $accordionHead = $accordion.querySelector('.js-accordion-head');
    const $accordionBody = $accordion.querySelector('.js-accordion-body');

    $accordionHead.addEventListener('click', (e) => {
      e.preventDefault();

      // detailsが閉じている場合
      if(!$accordion.open) {
        $accordion.open = true;
        $accordionBody.animate({
          height: ['0px', `${$accordionBody.scrollHeight}px`]
        }, accordionSlideOptions);

      // detailsが開いている場合
      } else {
        const closeAnimation = $accordionBody.animate({
          height: [`${$accordionBody.scrollHeight}px`, '0px']
        }, accordionSlideOptions);
        // 閉じるアニメーション完了後にopen属性を除去
        closeAnimation.addEventListener('finish', function() {
          $accordion.open = false;
        });
      }
    });
  });
});

アニメーション処理中はopen属性を付与した状態にする必要があるため、デフォルトのdetailsの処理は止めた上でJavaScriptで付け替えを行っています。
detailsの開閉アニメーションのデモページ

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2025年12月
 123456
78910111213
14151617181920
21222324252627
28293031