details要素とsummary要素でアコーディオン(折り畳み)を作る方法
2023年 2月 8日 Posted 藤原(フロントエンドエンジニア)
よくある質問ページや、Q&A、商品情報等の詳細をアコーディオン(折り畳み)でコーディングする際、制作する人によって色々な実装方法があると思います。JavaScript(jQueryを含む)を使って作ることも多いですね。今回はdetails要素とsummary要素を使用して作ってみようと思います。
折りたたみ表示でよく見るコーディングについて
ネットで色々と調べものをしていると出てくる「よくある質問」ページ。
どのようなコーディングをしているのかソースを調べてみました。
dt要素とdd要素 | dt要素(質問)をクリックで、dd要素(答え)を表示 |
---|---|
ul要素やol要素 | li要素内に質問と答えをコーディング |
div要素とp要素 | p要素で質問と答えをコーディング |
h要素とdiv要素 | h要素(質問)をクリックで、div要素(答え)を表示 |
input要素とdiv要素 | input要素(質問)をクリックで、div要素(答え)を表示 |
buttun要素とdiv要素 | buttun要素(質問)をクリックで、div要素(答え)を表示 |
私自身も過去Q&Aページを作る際、dt要素・dd要素を用いて実装したことがあります。
作成する際、この中に含まれる意味が、dtは用語、ddが用語に対する説明としてコーディングするのが意味として近いものと思い、この要素を使用していました。
details要素とsummary要素とは
HTML 5.1 で勧告されて、HTML Living Standard で標準となっている要素です。
details要素
details要素は、備考や操作手順などの詳細情報を示すときに使います。
detailsの子要素としてsummaryを用いる場合は、summaryの内容が詳細情報の要約になります。
- * 子要素がない場合、ブラウザがdetailsの内容を要約するかもしれません。
- * details要素は脚注には適していません。(脚注であることを明示的に表す専用の要素はありません)
summary要素
summary要素は、summaryの親要素となるdetailsの内容のキャプション、説明を表す際に使います。summary要素は、details要素の最初の子としてのみ使用できます。
サポート状況
主要ブラウザ(IE・Opera Miniを除く)で問題なく使用できます。
なぜdetails要素とsummary要素で作るのか
コンテンツの意味をHTML要素で表現することができる
div要素やspan要素で「質問内容」とマークアップしてもそれは意味的要素を持たないものになります。p要素で「質問内容」とマークアップしてもテキストの段落として認識されます。summary要素に「質問内容」とマークアップすると、details要素の要約、キャプション、説明として認識されます。
JavaScript(jQueryを含む)に頼らず、少しのCSSの調整だけで作成することができる
以下の様に初期表示され、「質問内容の表示」をクリックで表示・非表示を切り替えることができます。詳細には複数の要素が配置できます。p要素だけではなく、ul要素やol要素など使っても大丈夫です。
質問内容の表示
答えが表示
<details>
<summary>質問内容の表示</summary>
<p>答えが表示</p>
</details>
表示されるとdetailsにopen属性が付与されます。
「<details open>」と記述することで、はじめからアコーディオンを開いておくことができます。
質問内容の表示
答えが表示
<details open>
<summary>質問内容の表示</summary>
<p>答えが表示</p>
</details>
特別なケアをしなくてもアクセシビリティ面で最適化されている
コンテンツの折り畳みと展開は、スクリーンリーダーおよびキーボード操作のみでも利用できます。
キーボード操作
Tabキーでsummary要素を選択、Enterキーを押下すると、詳細内容が展開されます。
スクリーンリーダー
スクリーンリーダーのNVDAを起動し、タブフォーカスとエンターキー・スペースキーでの開閉操作ができます。また、キーボードで操作すると、以下の様に読み上げられます。
- 折り畳み時 : 「ボタン、折りたたみ、質問内容の表示」の音声。
- 展開時 : 「展開」キーボード↓押下、「答えが表示」の音声。
- * Windows NVDAとChromeで検証
- * ChromiumでないEdgeは固定的に展開表示されます。
- * 非表示状態のdetails要素の中身はアクセシビリティツリーからは除外されます。
参考
- <details> と <summary> によるコンテンツの折り畳み / 展開
- NVDAを使ってWebアクセシビリティをテストする方法
- NVDA日本語版 ダウンロードと説明
- タコでもわかるWebアクセシビリティ① 〜概要編〜
CSSで見た目を調整してみる
以下の点に気を付けて調整してみました。
注意点
- ブラウザデフォルトのスタイルにより、▼(三角マーク) が表示される。
この三角マークは、display: list-item (箇条書きリストの「●」(丸)と同じプロパティ)によって表示されるもの。 - ただし、Safariは、display: list-itemではなく、::-webkit-details-marker 擬似要素によって表示される。
- summaryをホバーしてもポインター(指さしマーク)にならないので cursor: pointer;を指定。
上記を考慮して、以下の設定をします。
summary {
list-style: none;
cursor: pointer;
}
summary::-webkit-details-marker {
display: none;
}
上記を含め、見た目を変更してみました
開閉時の動きを滑らかにしてみたり、色々変更しても良いかと思います。
質問内容の表示
答えが表示
質問内容の表示
答えが表示
質問内容の表示
答えが表示
- 答えが表示
- 答えが表示
HTML
<div class="accordion-test">
<details>
<summary>質問内容の表示</summary>
<div class="contents">
<p>答えが表示</p>
</div>
</details>
<details>
<summary>質問内容の表示</summary>
<div class="contents">
<p>答えが表示</p>
</div>
</details>
<details>
<summary>質問内容の表示</summary>
<div class="contents">
<p>答えが表示</p>
<ul>
<li>答えが表示</li>
<li>答えが表示</li>
</ul>
</div>
</details>
</div>
CSS
.accordion-test summary{
position: relative;
list-style: none; /* デフォルトの三角形アイコンを消します */
padding: 15px 45px 15px 25px;
border:1px solid #000474;
cursor: pointer; /* ポインターを指さしマークに変更 */
}
.accordion-test summary::-webkit-details-marker {
display: none; /* Safariで表示されるデフォルトの三角形アイコンを消します */
}
.accordion-test summary::after{
position: absolute;
width: 15px;
height: 15px;
top: calc(50% - 10px);
right: 25px;
border-right: 4px solid #000474;
border-bottom: 4px solid #000474;
box-sizing: border-box;
content: "";
transform: rotate(45deg);
transition: top 0.4s ease-out, transform 0.4s ease-out;
}
.accordion-test details[open] summary::after{
top: calc(50% - 5px);
transform: rotate(-135deg);
}
.accordion-test .contents{
padding: 15px 45px;
background:#E8ECF7;
}
まとめ
いかがでしたか?コーディングが簡単になり、アクセシビリティの質をあげることができるdetails要素とsummary要素。ぜひぜひ使ってみてください!