アコーディオンは、見出しをクリックすると隠れている内容が表示され、もう一度クリックすると閉じるUIです。HTMLのdetails要素とsummary要素を使えば、JavaScriptを使用せずに開閉機能を実装できます。今回は、複数の項目を同時に開けるタイプと、1つの項目だけを開けるタイプの2種類を紹介します。
複数の項目を同時に開くタイプでは、見出しをクリックすると、その下に内容が表示されます。続けて別の見出しをクリックしても、先に開いた項目は閉じません。それぞれの項目を独立して開閉できるため、複数の内容を並べて確認できます。また、開いている見出しをもう一度クリックすると、その項目だけを閉じることができます。
一方、1つの項目だけを開くタイプでは、新しい見出しをクリックすると、それまで開いていた項目が自動的に閉じます。複数の内容が同時に表示されないため、確認したい情報を1つに絞ることができます。開いている見出しをもう一度クリックすれば、その項目も閉じられ、すべての項目が閉じた状態に戻ります。
この2種類は、どちらもHTMLとCSSだけで作成できます。複数開くタイプは各項目を自由に開閉でき、1つだけ開くタイプは別の項目を開くと前の項目が閉じるという違いがあります。この記事では、それぞれの動作をデモで比較しながら、JavaScriptを使わないアコーディオンの作り方を紹介します。
開閉アニメーションやクリック時の処理をJavaScriptで制御したい場合は、アコーディオンの作り方|複数の項目を同時に開く方法と1つだけ開く方法も参考にしてください。
デモ
それぞれの項目を独立して開閉できるアコーディオンです。
見出し1
見出し2
見出し3
見出し1を開いたまま、見出し2をクリックしてください。複数の項目を同時に開けます。
別の項目を開くと、前の項目が自動的に閉じるアコーディオンです。
見出し1
見出し2
見出し3
見出し1を開いたあと、見出し2をクリックしてください。見出し1が閉じて見出し2だけが開きます。
Q 他のアイコンを使いたい場合はどうするの?
無料の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">
</head>
<body>
<!-- アコーディオン全体 -->
<div class="html-css-accordion_wrap">
<!-- 1つ目の項目 -->
<details class="html-css-accordion_item">
<!-- 開閉する見出し -->
<summary class="html-css-accordion_summary">
<!-- 見出しの文字 -->
<span class="html-css-accordion_label">見出し1</span>
<!-- 開閉状態を示すアイコン -->
<span class="html-css-accordion_icon" aria-hidden="true">
<!-- 閉じているときのプラスアイコン -->
<span class="html-css-accordion_icon-closed">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 4v16 M4 12h16"></path>
</svg>
</span>
<!-- 開いているときのマイナスアイコン -->
<span class="html-css-accordion_icon-open">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 12h16"></path>
</svg>
</span>
</span>
</summary>
<!-- 開いたときに表示する内容 -->
<div class="html-css-accordion_content">
1つ目の内容が表示されます。
</div>
</details>
<!-- 2つ目の項目 -->
<details class="html-css-accordion_item">
<summary class="html-css-accordion_summary">
<span class="html-css-accordion_label">見出し2</span>
<span class="html-css-accordion_icon" aria-hidden="true">
<span class="html-css-accordion_icon-closed">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 4v16 M4 12h16"></path>
</svg>
</span>
<span class="html-css-accordion_icon-open">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 12h16"></path>
</svg>
</span>
</span>
</summary>
<!-- 開いたときに表示する内容 -->
<div class="html-css-accordion_content">
2つ目の内容が表示されます。
</div>
</details>
<!-- 3つ目の項目 -->
<details class="html-css-accordion_item">
<summary class="html-css-accordion_summary">
<span class="html-css-accordion_label">見出し3</span>
<span class="html-css-accordion_icon" aria-hidden="true">
<span class="html-css-accordion_icon-closed">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 4v16 M4 12h16"></path>
</svg>
</span>
<span class="html-css-accordion_icon-open">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 12h16"></path>
</svg>
</span>
</span>
</summary>
<!-- 開いたときに表示する内容 -->
<div class="html-css-accordion_content">
3つ目の内容が表示されます。
</div>
</details>
</div>
</body>
</html>
1つだけ開くアコーディオン
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- 文字コード -->
<meta charset="UTF-8">
<!-- スマートフォン対応 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ページタイトル -->
<title>1つだけ開くアコーディオン</title>
<!-- CSSファイル -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- アコーディオン全体 -->
<div class="html-css-accordion_wrap">
<!--
同じname属性を持つdetails要素は、
同時に1つの項目だけを開くことができます。
JavaScriptを使用する必要はありません。
-->
<!-- 1つ目の項目 -->
<details class="html-css-accordion_item" name="html-css-accordion-single">
<!-- 開閉する見出し -->
<summary class="html-css-accordion_summary">
<!-- 見出しの文字 -->
<span class="html-css-accordion_label">見出し1</span>
<!-- 開閉状態を示すアイコン -->
<span class="html-css-accordion_icon" aria-hidden="true">
<!-- 閉じているときのプラスアイコン -->
<span class="html-css-accordion_icon-closed">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 4v16 M4 12h16"></path>
</svg>
</span>
<!-- 開いているときのマイナスアイコン -->
<span class="html-css-accordion_icon-open">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 12h16"></path>
</svg>
</span>
</span>
</summary>
<!-- 開いたときに表示する内容 -->
<div class="html-css-accordion_content">
1つ目の内容が表示されます。
</div>
</details>
<!-- 2つ目の項目 -->
<details class="html-css-accordion_item" name="html-css-accordion-single">
<summary class="html-css-accordion_summary">
<span class="html-css-accordion_label">見出し2</span>
<span class="html-css-accordion_icon" aria-hidden="true">
<span class="html-css-accordion_icon-closed">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 4v16 M4 12h16"></path>
</svg>
</span>
<span class="html-css-accordion_icon-open">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 12h16"></path>
</svg>
</span>
</span>
</summary>
<!-- 開いたときに表示する内容 -->
<div class="html-css-accordion_content">
2つ目の内容が表示されます。
</div>
</details>
<!-- 3つ目の項目 -->
<details class="html-css-accordion_item" name="html-css-accordion-single">
<summary class="html-css-accordion_summary">
<span class="html-css-accordion_label">見出し3</span>
<span class="html-css-accordion_icon" aria-hidden="true">
<span class="html-css-accordion_icon-closed">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 4v16 M4 12h16"></path>
</svg>
</span>
<span class="html-css-accordion_icon-open">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 12h16"></path>
</svg>
</span>
</span>
</summary>
<!-- 開いたときに表示する内容 -->
<div class="html-css-accordion_content">
3つ目の内容が表示されます。
</div>
</details>
</div>
</body>
</html>
コードをコピーする場合 使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。 サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
Q ダウンロードしたけど、これをネット上で動かすにはどうするの?
Googleアカウントがあれば、InfinityFreeで無料サーバーを作成して、ダウンロードしたサンプルをネット上で動かせます。
InfinityFreeを初めて利用する場合は①から、すでにサーバーを作成している場合は②へ進んでください。
ファイル構成と設置方法
今回は、複数の項目を同時に開くアコーディオンと、1つの項目だけを開くアコーディオンを、それぞれ独立したサンプルとして用意しています。どちらもHTMLとCSSだけで動作し、JavaScriptは必要ありません。セクション③から使用したいタイプの「サンプル一式をダウンロード」をクリックすると、そのタイプのindex.htmlとstyle.cssをまとめて取得できます。2つのサンプルは同じファイル構成ですが、HTMLのdetails要素に指定する属性が異なります。
sample/
├── index.html
└── style.css
各ファイルの役割
index.htmlには、アコーディオンを構成するdetails要素とsummary要素、見出しの文字、開いたときに表示する内容、開閉状態を示すSVGアイコンを記述しています。1つだけ開くタイプでは、各details要素に同じname属性を指定しています。style.cssでは、項目の枠線や余白、文字の大きさ、プラス・マイナスアイコンの切り替えなどを設定しています。
設置方法・使い方
使用したいアコーディオンのZIPをダウンロードして展開すると、sampleフォルダ内に2つのファイルが入っています。そのままindex.htmlをブラウザで開けば、アコーディオンの動作を確認できます。見出しをクリックすると内容が表示され、もう一度クリックすると閉じます。複数開くタイプでは別の項目を開いても前の項目が残り、1つだけ開くタイプでは新しい項目を開くと前の項目が閉じます。既存のWebサイトへ組み込む場合は、必要なHTMLとCSSをそれぞれのファイルへ追加してください。
複数の項目を同時に開ける仕組み
複数開くタイプでは、各details要素を独立して配置しています。details要素は開閉状態を管理するHTML要素で、内部のsummary要素がクリックできる見出しになります。
<!-- 1つ目の項目 -->
<details class="html-css-accordion_item">
<!-- 開閉する見出し -->
<summary class="html-css-accordion_summary">
このタイプではdetails要素にname属性を指定していないため、各項目が個別に開閉します。見出し1を開いたまま見出し2をクリックしても、見出し1の開閉状態は変わりません。複数の説明を同時に表示したい場合に使用できます。
1つの項目だけを開ける仕組み
1つだけ開くタイプでは、各details要素に同じname="html-css-accordion-single"を指定しています。このname属性によってdetails要素がグループ化され、同じグループ内では1つの項目だけを開けるようになります。
<!-- 1つ目の項目 -->
<details class="html-css-accordion_item" name="html-css-accordion-single">
2つ目と3つ目のdetails要素にも同じname属性を指定しています。例えば見出し1が開いている状態で見出し2をクリックすると、ブラウザが見出し1を自動的に閉じ、見出し2の内容を表示します。この動作はHTMLの標準機能によって実現しているため、JavaScriptで開閉状態を管理する必要はありません。また、開いている見出しをもう一度クリックすれば、すべて閉じた状態にできます。
プラス・マイナスアイコンの切り替え
どちらのタイプも、閉じているときはプラス、開いているときはマイナスのSVGアイコンを表示します。style.cssでは、details要素が開いたときに付くopen属性を利用して、表示するアイコンを切り替えています。
/* 初期状態ではマイナスアイコンを非表示 */
.html-css-accordion_icon-open {
display: none;
}
/* 開いているときはプラスアイコンを非表示 */
.html-css-accordion_item[open] .html-css-accordion_icon-closed {
display: none;
}
/* 開いているときはマイナスアイコンを表示 */
.html-css-accordion_item[open] .html-css-accordion_icon-open {
display: flex;
}
.html-css-accordion_item[open]は、open属性が付いているdetails要素を対象にするCSSセレクタです。項目を開くとプラスアイコンが非表示になり、代わりにマイナスアイコンが表示されます。閉じると元の状態へ戻ります。
カスタマイズできる内容
見出しの文字や開いたときに表示する文章は、index.htmlの.html-css-accordion_labelと.html-css-accordion_contentを編集します。項目を増やしたい場合は、details要素をまとめて複製し、見出しと内容を書き換えてください。1つだけ開くタイプでは、追加したdetails要素にも同じname属性を指定する必要があります。枠線や背景色、文字色、アイコンの色はstyle.cssから変更できます。
数値調整
style.cssで以下の数値を変更できます。
・.html-css-accordion_wrapのmax-width: 700px;
アコーディオン全体の最大横幅です。値を小さくするとコンパクトになり、大きくすると横に広がります。
・.html-css-accordion_itemのmargin: 0 0 12px;
項目同士の間隔です。値を大きくすると上下の間隔が広がります。
・.html-css-accordion_itemのborder-radius: 12px;
項目の角丸の大きさです。値を大きくすると丸みが強くなります。
・.html-css-accordion_summaryのpadding: 16px 18px;
見出し部分の内側余白です。16pxが上下、18pxが左右の余白を表し、それぞれ変更できます。
レスポンシブ対応
アコーディオン全体にはwidth: 100%;とmax-width: 700px;を指定しているため、親要素の幅に合わせて縮小します。また、style.cssには画面幅640px以下のメディアクエリを用意しています。スマートフォンでは最大横幅を100%にし、見出しとアイコンの間隔を16pxから12pxへ変更します。長い見出しも折り返して表示できるため、PC・タブレット・スマートフォンで利用できます。
コメント