スッとスライドして開閉するアコーディオンの作り方

アコーディオン
無料ツール
アコーディオンを自由に作成

見出し・内容・開閉方法・色・サイズ・アイコンなどを設定して、HTML・CSS・JavaScriptを自動生成できます。

アコーディオン作成ツールを使う
新しいタブで開きます

アコーディオンは、見出しをクリックすることで隠れている内容を表示・非表示にできるUIです。一般的なアコーディオンでは内容が瞬時に切り替わりますが、スライドアニメーションを加えると、表示領域が上下に滑らかに伸縮しながら開閉します。急に内容が現れたり消えたりしないため、画面の変化を自然に見せることができます。

今回紹介するのは、内容がスッとスライドして開閉するアコーディオンです。見出しをクリックすると内容が上から下へ広がり、もう一度クリックすると下から上へ縮みながら閉じます。開閉時間は600ms(0.6秒)に設定し、フェードによる透明度の変化は加えず、高さの変化だけで動きを表現しています。

スライドアニメーションは、CSSのgrid-template-rowsとtransitionを組み合わせて実装します。JavaScriptではクリックした項目の開閉状態を切り替えるだけなので、複雑な高さの計算は必要ありません。また、複数の項目を同時に開くことができ、それぞれ独立して開閉できます。

この記事では、HTML・CSS・JavaScriptを使って、スライドアニメーション付きアコーディオンを作る方法を紹介します。実際のデモで開閉の動きを確認しながら、アニメーションの仕組みや開閉速度の調整方法を解説します。

デモ

スライドアコーディオン

見出しをクリックすると、内容が滑らかにスライドして開閉します。

アコーディオンは、見出しをクリックして内容の表示・非表示を切り替えられるUIです。
内容の表示領域が上下に滑らかに伸縮します。フェードを使わず、高さの変化だけで自然な開閉を表現しています。
CSSのtransitionで指定している400msを変更すると、開閉速度を調整できます。数値を小さくすると速く、大きくするとゆっくり動きます。

見出しをクリックすると、内容が上下にスライドして開閉します。複数の項目を同時に開くこともでき、開閉途中にもう一度クリックすると動作が切り替わります。

Q 他のアイコンを使いたい場合はどうするの?
A

無料のSVGアイコン作成ツールを使って、用途に合ったアイコンを作成できます。

コードをコピーして使おう!

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

  <!-- 文字コード -->
  <meta charset="UTF-8">

  <!-- スマートフォン対応 -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <!-- ページタイトル -->
  <title>スライドアコーディオン</title>

  <!-- CSSファイル -->
  <link rel="stylesheet" href="style.css">

  <!-- JavaScriptファイル -->
  <script src="script.js" defer></script>

</head>
<body>

  <!-- アコーディオン全体 -->
  <div class="slide-accordion_wrap">

    <!-- 1つ目の項目 -->
    <div class="slide-accordion_item">

      <!-- 開閉ボタン -->
      <button class="slide-accordion_button" type="button" aria-expanded="false">

        <!-- 見出し -->
        <span class="slide-accordion_label">アコーディオンとは?</span>

        <!-- 開閉アイコン -->
        <span class="slide-accordion_icon" aria-hidden="true">

          <!-- 閉じているときのプラスアイコン -->
          <span class="slide-accordion_icon-closed">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <path d="M12 4v16 M4 12h16"/>
            </svg>
          </span>

          <!-- 開いているときのマイナスアイコン -->
          <span class="slide-accordion_icon-open">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <path d="M4 12h16"/>
            </svg>
          </span>

        </span>

      </button>

      <!-- 開閉する内容 -->
      <div class="slide-accordion_content">
        <div class="slide-accordion_content-inner">アコーディオンは、見出しをクリックして内容の表示・非表示を切り替えられるUIです。</div>
      </div>

    </div>

    <!-- 2つ目の項目 -->
    <div class="slide-accordion_item">

      <!-- 開閉ボタン -->
      <button class="slide-accordion_button" type="button" aria-expanded="false">

        <!-- 見出し -->
        <span class="slide-accordion_label">スライド開閉の特徴は?</span>

        <!-- 開閉アイコン -->
        <span class="slide-accordion_icon" aria-hidden="true">

          <!-- 閉じているときのプラスアイコン -->
          <span class="slide-accordion_icon-closed">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <path d="M12 4v16 M4 12h16"/>
            </svg>
          </span>

          <!-- 開いているときのマイナスアイコン -->
          <span class="slide-accordion_icon-open">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <path d="M4 12h16"/>
            </svg>
          </span>

        </span>

      </button>

      <!-- 開閉する内容 -->
      <div class="slide-accordion_content">
        <div class="slide-accordion_content-inner">内容の表示領域が上下に滑らかに伸縮します。フェードを使わず、高さの変化だけで自然な開閉を表現しています。</div>
      </div>

    </div>

    <!-- 3つ目の項目 -->
    <div class="slide-accordion_item">

      <!-- 開閉ボタン -->
      <button class="slide-accordion_button" type="button" aria-expanded="false">

        <!-- 見出し -->
        <span class="slide-accordion_label">開閉速度は変更できる?</span>

        <!-- 開閉アイコン -->
        <span class="slide-accordion_icon" aria-hidden="true">

          <!-- 閉じているときのプラスアイコン -->
          <span class="slide-accordion_icon-closed">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <path d="M12 4v16 M4 12h16"/>
            </svg>
          </span>

          <!-- 開いているときのマイナスアイコン -->
          <span class="slide-accordion_icon-open">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <path d="M4 12h16"/>
            </svg>
          </span>

        </span>

      </button>

      <!-- 開閉する内容 -->
      <div class="slide-accordion_content">
        <div class="slide-accordion_content-inner">CSSのtransitionで指定している600msを変更すると、開閉速度を調整できます。数値を小さくすると速く、大きくするとゆっくり動きます。</div>
      </div>

    </div>

  </div>

</body>
</html>
コードについて 本記事のコードはサンプルコードです。ご利用前に必ず動作確認を行ってください。 免責事項 本コードの利用により発生した損害について、当サイトは一切の責任を負いません。

コードをコピーする場合 使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。 サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
Q ダウンロードしたけど、これをネット上で動かすにはどうするの?
A

Googleアカウントがあれば、InfinityFreeで無料サーバーを作成して、ダウンロードしたサンプルをネット上で動かせます。

InfinityFreeを初めて利用する場合は①から、すでにサーバーを作成している場合は②へ進んでください。

ファイル構成と設置方法

スライドアコーディオンのサンプルは、HTML・CSS・JavaScriptの3つのファイルで構成されています。HTMLに3つの開閉項目とプラス・マイナスのSVGアイコンを配置し、CSSで表示デザインとスライドアニメーションを設定しています。JavaScriptはクリックされた項目の開閉状態を切り替える役割を持ち、複数の項目をそれぞれ独立して操作できる仕組みです。

sample/
├── index.html
├── style.css
└── script.js

各ファイルの役割
index.htmlには、アコーディオンの見出し、開閉する文章、プラス・マイナスのSVGアイコンを記述しています。style.cssでは、各項目の枠線や余白、文字色に加え、grid-template-rowsを使った開閉アニメーションを設定しています。script.jsでは、クリックされた項目にis-openクラスを付け外しし、開閉状態を管理しています。

設置方法・使い方
「サンプル一式をダウンロード」からZIPファイルをダウンロードして展開します。展開したindex.html・style.css・script.jsを同じフォルダに配置し、ブラウザでindex.htmlを開くとアコーディオンが表示されます。見出しをクリックすると内容が下方向へスライドして開き、もう一度クリックすると上方向へ縮みながら閉じます。ほかの項目を開いても、すでに開いている項目は閉じず、複数の内容を同時に表示できます。

高さを変化させてスライド開閉する仕組み
スライドアニメーションは、style.cssのgrid-template-rowsで実現しています。閉じているときは0frで内容の表示領域を縮め、開いたときは1frに変更して内容の高さまで広げます。transitionを指定することで、この高さの変化が瞬時に切り替わらず、滑らかな動きになります。

/* 開閉する内容 */
.slide-accordion_content {
  display: grid; /* 高さをアニメーションさせるためにグリッドを使用 */
  grid-template-rows: 0fr; /* 初期状態では内容を閉じる */
  transition: grid-template-rows 600ms cubic-bezier(0.4, 0, 0.2, 1); /* 開閉時間600ms。値を小さくすると速く、大きくすると遅くなる */
  background: #ffffff; /* 内容の背景色 */
  color: #4b5563; /* 内容の文字色 */
  font-size: 16px; /* 内容の文字サイズ */
  font-weight: 400; /* 内容の文字の太さ */
  line-height: 1.8; /* 内容の行間 */
}

/* 開いたときの高さ */
.slide-accordion_item.is-open .slide-accordion_content {
  grid-template-rows: 1fr; /* 内容の高さに合わせて広げる */
}

このコードでは、内容の高さをJavaScriptで計算する必要がありません。文章の長さに合わせて表示領域が広がるため、各項目の文章量が異なっていても同じ仕組みで開閉できます。また、透明度を変更するopacityは使用していないため、フェードせずに高さだけが変化します。

クリックした項目だけを開閉する仕組み
script.jsでは、各ボタンにクリックイベントを設定しています。クリックされたボタンの親要素を取得し、その項目のis-openクラスだけを切り替えます。

/* クリックしたボタンの親項目を取得 */
const item = button.parentElement;

/* クリックした項目だけを開閉する */
item.classList.toggle("is-open");

/* 開閉状態をアクセシビリティ属性へ反映 */
button.setAttribute(
  "aria-expanded",
  item.classList.contains("is-open") ? "true" : "false"
);

classList.toggle("is-open")は、クラスが付いていなければ追加し、付いていれば削除する処理です。このクラスの有無によってCSSの開閉設定が切り替わります。ほかの項目のクラスは変更しないため、複数のアコーディオンを同時に開いたままにできます。aria-expandedも開閉状態に合わせて更新し、ボタンが開いているか閉じているかを支援技術へ伝えます。

カスタマイズできる内容
見出しや開閉する文章は、index.htmlのslide-accordion_labelとslide-accordion_content-innerを書き換えることで変更できます。項目を増やしたい場合は、slide-accordion_item全体を複製して文章を変更します。JavaScriptは各ボタンをまとめて取得しているため、項目を追加するたびにクリック処理を書き足す必要はありません。

枠線や角丸、文字色などのデザインはstyle.cssで変更できます。slide-accordion_itemのborderやborder-radiusを変更すると項目の外観が変わり、slide-accordion_iconのcolorを変更するとプラス・マイナスアイコンの色を調整できます。

数値調整
開閉速度は、style.cssのslide-accordion_contentにあるtransition: grid-template-rows 600ms cubic-bezier(0.4, 0, 0.2, 1);で調整できます。600msは0.6秒を表し、300msにすると速く、900msにするとゆっくり開閉します。開くときと閉じるときの両方に同じ時間が適用されます。

全体の最大横幅はslide-accordion_wrapのmax-width: 700px;で設定しています。値を大きくすると横に広がり、小さくするとコンパクトになります。また、slide-accordion_itemのmargin: 0 0 12px;を変更すると、各項目の上下間隔を調整できます。

レスポンシブ対応
style.cssでは、アコーディオン全体をwidth: 100%;とmax-width: 700px;で設定し、画面幅に合わせて縮小できるようにしています。さらに、画面幅が640px以下になるとメディアクエリが適用され、見出しとアイコンの間隔が16pxから12pxに変わります。長い見出しは折り返され、アイコンは縮小されないため、スマートフォンでも開閉ボタンを操作できます。


こちらもおすすめ


コメント