<details> と <summary> によるコンテンツの折り畳み / 展開

ウェブコンテンツの UI 設計において、デフォルトでは全体俯瞰を重視するなどの理由で概要コンテンツのみを提示し、ユーザーの任意で詳細コンテンツを展開表示させたい、というケースがあるかと思います。まさにそのための HTML 要素として、<details> と <summary> の組み合わせがあります。

Can I Use...」によると、IE と Opera Mini 以外は、<details> および <summary> 要素をサポートしているようです。Windows 10 のデフォルトブラウザである Edge も対応するようになった (†) ので、デスクトップ / モバイルを問わず、概ね問題なく使えるようになってきたのかな、という印象です。

† ただしレガシー版 (Chromium でない) Edge の場合、折り畳み / 展開のインタラクションはできず、IE と同様、固定的に展開表示された形になります。

実装例

以下、実装例です。グラフによる視覚的な情報提示があって、ユーザーの任意で、データの表 (テーブル) を見ることができる、といった UI を想定してみました。

See the Pen <details> <summary> の実験 by Kazuhiko Tsuchiya (@caztcha) on CodePen.

詳細コンテンツが展開表示されると <details> 要素に open 属性付与され、詳細コンテンツが折り畳まれると open 属性が消えます。こうした属性の動的な制御が、JavaScript なしで行われます。

上の例では CSS で若干のスタイリングを施していますが (summary のマーカー表示を独自のアイコンにカスタマイズするなど)、基本は HTML だけで動的に折りたたみ / 展開が実現できます。

実装上の留意点

<summary> 要素をマウスオーバー (hover) したときのマウスポインターの形状が、デフォルトでは「I ビーム」になってしまうようです (クリッカブルでないテキストと同じ挙動)。クリック可能であることを明示するために、「人差し指」型にする (summary{cursor:pointer;}) とよいかもしれません。

また、<summary> のラベルは、詳細コンテンツが折り畳まれていても展開されていても適用できる言葉にしておくとよいでしょう。たとえば「データ一覧を開く」のように特定の状態 (折り畳まれた状態) にのみフィットする表現をしてしまうと、展開表示されているときに不自然になってしまうので、「データ一覧の表示」のように、状態に依存しない表現にします。こうしておけば、Edge のように固定的に展開表示される (折り畳み / 展開のインタラクションができない) ブラウザにも対応できますし、スクリーンリーダーでの読み上げ (‡) も自然になります。

‡ スクリーンリーダーでは、<summary> にフォーカスが当たると、ラベルの読み上げに続いて折り畳まれているのかどうかの状態も併せて読み上げられる仕組みになっています。ですので、ラベル自体はむしろ特定の状態に依存しない表現にするのがよいと思います。

あと、適宜 Edge (レガシー版) 対応もしておきましょう。summary のマーカーアイコン (クリックできそうに見える手がかり) を消す、summary 上をマウスオーバー (hover) したときのマウスポインター形状をリセットする、といった具合です。

アクセシビリティの検証

キーボード操作

<details> と <summary> によるコンテンツの折り畳み / 展開は、キーボード操作のみでも利用可能です。[Tab] キーによって <summary> 要素にフォーカスを当てることができるので、その状態で [Enter] キーを押すことで、詳細コンテンツの開閉ができます。詳細コンテンツが展開されると、その中のクリッカブルな要素 (リンクなど) が自然にタブオーダーに含まれるようになります。

スクリーンリーダーでの読み上げ

NVDA と VoiceOver で確認した限りでは、以下のように概ね問題ないと言えそうです。

Windows NVDA + Chrome / Firefox / Edge (Chromium)
  • 折り畳み時 : 「{summary のラベル}、ボタン、折り畳み。」
  • 展開時 : 「{summary のラベル}、ボタン、展開。」
macOS VoiceOver + Safari
  • 折り畳み時 : 「{summary のラベル}、下位項目が非表示になりました。summary。」
  • 展開時 : 「{summary のラベル}、じあいだひろく (字間広く)。summary。」
Chrome の場合、「summary」の代わりに「三角形の展開ボタン」と読み上げられます。
iOS VoiceOver + Safari / Chrome
  • 折り畳み時 : 「{summary のラベル}、隠されました。展開するには、ダブルタップします。」
  • 展開時 : 「{summary のラベル}」

macOS VoiceOver で、詳細コンテンツ展開時に読み上げられる「じあいだひろく (字間広く)」というのが日本語として意味不明ですが、別のケースでの展開表示 (aria-expanded="true") においても同様に、このような読み上げになってしまいます。コンテンツ側ではなく、Apple 側でローカライズの修正がなされれば解決するので、待ちたいと思います。