【CSSのみ】details要素とsummary要素でアコーディオンを作る

ノートパソコン商用無料イラスト Web制作

よくある質問ページやQ&A等の詳細でよく使うアコーディオンを実装する際、JavaScript(jQueryを含む)をはじめ色々な実装方法がありますが、今回はdetails要素とsummary要素を使用してCSSのみで作る方法をご紹介します。

アコーディオンでよく見る実装方法

一般的に「よくある質問」ページはどのような実装をされているのか、様々なサイトを調査しました。

dt要素とdd要素dt要素(質問)をクリックで、dd要素(答え)を表示
ul要素やol要素li要素内に質問と答えをコーディング
div要素とp要素p要素で質問と答えをコーディング
h要素とdiv要素h要素(質問)をクリックで、div要素(答え)を表示
input要素とdiv要素input要素(質問)をクリックで、div要素(答え)を表示
buttun要素とdiv要素buttun要素(質問)をクリックで、div要素(答え)を表示

私が以前、「よくある質問」ページを作った際はdt要素・dd要素を用いて実装していました。
dtは用語、ddが用語に対する説明としてコーディングするのが意味として近いものと思い、この要素を使用していました。

details要素とsummary要素とは

HTML 5.1 で勧告されて、HTML Living Standard で標準となっている要素です。
HTML Living Standard The details element
HTML Living Standard The summary element

details要素

details要素は、備考や操作手順などの詳細情報を示すときに使用します。
detailsの子要素としてsummaryを用いる場合は、summaryの内容が詳細情報の要約になります。

summary要素

summary要素は、summaryの親要素となるdetailsの内容のキャプション、説明を表す際に使用します。summary要素は、details要素の最初の子としてのみ使用できます。

サポート状況

主要ブラウザ(IE・Opera Miniを除く)では問題なく使用できるようです。
Can I use - details
Can I use - summary

なぜdetails要素とsummary要素なのか

コンテンツの意味をHTMLで表現することができる

div要素やspan要素で「質問内容」とマークアップしてもそれは意味を持たないものになります。p要素で「質問内容」とマークアップしてもテキストの段落として認識されますが、summary要素に「質問内容」とマークアップすると、details要素の要約、キャプション、説明として認識されます。

JavaScriptに頼らず、少しのCSSの調整だけで作成することができる

summary要素をクリックすると、親のdetails要素の開閉状態を切り替えることができます。
また、<details open>のようにopen属性を付与することではじめからアコーディオンを開いておくことができます。これらを利用することで、JavaScriptを使わずともhtml+CSSだけのシンプルな構成で開閉アクションを実装することが可能です。

既にアクセシビリティ面で最適化されている

コンテンツの折り畳みと展開は、スクリーンリーダーおよびキーボード操作のみでも利用できます。

キーボード操作

Tabキーでsummary要素を選択、Enterキーを押下すると、詳細内容が展開されます。

スクリーンリーダー

スクリーンリーダーのNVDAを起動し、タブフォーカスとエンターキー・スペースキーでの開閉操作ができます。また、キーボードで操作すると、以下の様に読み上げられます。

  • 折り畳み時 : 「ボタン、折りたたみ、質問内容の表示」の音声。
  • 展開時 : 「展開」キーボード↓押下、「答えが表示」の音声。

DEMO

See the Pen Accordion by yoshio (@creata-dsgni) on CodePen.

注意点

  • ブラウザデフォルトのスタイルにより、▼(三角マーク) が表示されてしまう。
    この▼は、display: list-item によって表示されるもので、スタイルの調整が必要。
  • ただし、Safariは、display: list-itemではなく、::-webkit-details-marker 擬似要素によって表示される。
  • summaryをホバーしてもポインター(指さしマーク)にならないので cursor: pointer;を指定する必要がある。
タイトルとURLをコピーしました