詳細と概要

非常に便利な詳細要素と概要要素の仕組みと、それらを使用する場所について説明します。

展開矢印(開示ウィジェットとも呼ばれます)は、コンテンツの表示と非表示を切り替えるユーザー インターフェース コントロールです。web.dev でこのページをご覧になっていて、ビューポートの幅が 106 em 未満の場合、[このページの内容] をクリックすると、このセクションの目次が表示されます。表示されない場合は、ブラウザを縮小して、このページの目次ナビゲーションをエキスパンダー矢印として表示します。

アコーディオンのグラフィカル ユーザー インターフェースは、縦に積み重ねられた一連の開示ウィジェットです。アコーディオンの一般的なユースケースは、よくある質問(FAQ)ページです。この場合、アコーディオン FAQ には表示される質問のリストが含まれます。クリックすると、質問が展開され、その質問の回答が表示されます。

jQuery には、少なくとも 2009 年からアコーディオン UI パターンが含まれています。元の JavaScript を使用しないアコーディオン ソリューションでは、各 FAQ の質問を <label> にし、その後にラベル付けされたチェックマークを付け、チェックマークがオンになったときに <div> の回答を表示していました。CSS は次のようになります。

#FAQ [type="checkbox"] + div.answer {
  /* all the answer styles */
  display: none;
}
#FAQ [type="checkbox"]:checked + div.answer {
  display: block;
}

履歴が必要な理由JavaScript やフォーム コントロールのハックを使用しないアコーディオンなどの開示ウィジェットは、比較的最近追加されたものです。<details> 要素と <summary> 要素は、2020 年 1 月以降に最新のブラウザで完全にサポートされるようになりました。セマンティック HTML を使用して、機能的ではあるものの、あまり魅力的ではない開示ウィジェットを作成できるようになりました。

<details> 要素と <summary> 要素だけで十分です。これらは、コンテンツの展開と折りたたみを処理する組み込みの方法です。ユーザーが <summary> をクリックまたはタップするか、<summary> にフォーカスがあるときに Enter キーを離すと、親 <details> のコンテンツが切り替わって表示されます。

すべてのセマンティック コンテンツと同様に、デフォルトの機能と外観を段階的に強化できます。この例では、CSS が少しだけ追加されています。

つまり、この CodePen(およびすべての CodePen サンプル)には JavaScript がありません。

open 属性を使用して表示を切り替える

<details> 要素は開示ウィジェット コンテナです。<summary> は、親の <details> の概要または凡例です。概要は常に表示され、親の残りのコンテンツの表示を切り替えるボタンとして機能します。<summary> を操作すると、<details> 要素の open 属性が切り替わり、自己ラベル付きの概要の兄弟要素の表示が切り替わります。

open 属性はブール値の属性です。値の有無にかかわらず、この属性が存在する場合は、すべての <details> コンテンツがユーザーに表示されることを示します。open 属性がない場合は、<summary> の内容のみが表示されます。

open 属性は、ユーザーがコントロールを操作すると自動的に追加、削除されるため、CSS で使用して、要素の状態に基づいて異なるスタイルを設定できます。

複数の <details> 要素(それぞれに <summary> 子要素がある)のリストを使用してアコーディオンを作成できます。HTML で open 属性を省略すると、ページが読み込まれたときに <details> がすべて折りたたまれ、見出しのみが表示されます。各見出しは、親の <details> 内の残りのコンテンツを開くためのものです。HTML に open 属性を含めると、ページの読み込み時に <details> が展開され、コンテンツが表示されます。

折りたたまれたコンテンツは DOM の一部ではありませんが、一部のブラウザでは検索可能で、他のブラウザでは検索できません。Edge または Chrome で検索すると、検索語句を含む詳細が展開され、その語句が出現した場所が表示されます。この動作は Firefox や Safari では再現されません。

<summary><details> 要素の最初の子でなければなりません。これは、ネストされている親 <details> 要素の残りのコンテンツの概要、キャプション、凡例を表します。<summary> 要素のコンテンツには、段落内で使用できる見出しコンテンツ、プレーン テキスト、HTML を指定できます。

概要マーカーを切り替える

前の 2 つの Codepen では、summary の inline-start 側に矢印があります。通常、画面に表示される展開矢印は、開閉状態を示すために回転(またはねじれ)する小さな三角形と、その横のラベルで構成されます。<summary> 要素の内容は、開示ウィジェットのラベルになります。

各セクションの上部にある回転する矢印は、<summary> 要素に設定された ::marker です。リスト項目と同様に、<summary> 要素は list-style 省略形プロパティと、list-style-type などのその長形プロパティをサポートしています。CSS を使用して開閉用三角をスタイル設定できます。たとえば、使用するマーカーを三角から他の箇条書きタイプ(list-style-image を使用した画像など)に変更できます。

他のスタイルを適用するには、details summary::marker と同様のセレクタを使用します。::marker 疑似要素は、限られた数のスタイルのみを受け入れます。::marker を削除して、スタイル設定が容易な ::before に置き換えるのは一般的な方法です。CSS スタイルによって、生成されたコンテンツのスタイルが open 属性の有無に基づいてわずかに変更されます。list-style: none を設定して開示ウィジェット アイコンを削除したり、マーカーのコンテンツnone に設定したりできますが、要約コンテンツを切り替えてコンテンツを表示 / 非表示にすることを視覚的に示すインジケーターは常に含める必要があります。

details summary::before {
  /* all the styles */
}
details[open] summary::before {
  /* changes applied when open only */
}

この例では、デフォルトのマーカーを削除し、生成されたコンテンツを追加して、詳細が閉じている場合は + を、詳細が開いている場合は - を作成します。

詳細ブロックをデフォルトで開く場合は、開始 <details> タグに open 属性を含めます。また、各ダイアログの間にスペースを追加し、生成されたコンテンツで作成されたマーカーの回転を切り替えて、外観を改善することもできます。

エラーの処理方法

<summary> を含めない場合、ブラウザはマーカーと「details」という単語を含む <summary> を作成します。この概要は シャドー ルートの一部であるため、作成者の CSS 概要スタイルは適用されません。

<summary> を含めても、それが <details> の最初の要素でない場合、ブラウザは概要を正しく表示します。概要にリンク、ラベル、その他のインタラクティブな要素を含めてもエラーにはなりませんが、ブラウザはインタラクティブなコンテンツ内のインタラクティブなコンテンツを異なる方法で処理します。

たとえば、概要にリンクを含めると、一部のブラウザでは概要とリンクの両方がデフォルトのタブ順に追加されますが、他のブラウザではデフォルトでリンクにフォーカスされません。<summary> にネストされた <label> をクリックすると、一部のブラウザでは関連付けられたフォーム コントロールにフォーカスが移動します。他のブラウザでは、フォーム コントロールにフォーカスが移動し、<details> が開閉されます。

HTMLDetailsElement インターフェース

すべての HTML 要素と同様に、HTMLDetailsElementHTMLElement からすべてのプロパティ、メソッド、イベントを継承し、open インスタンス プロパティと toggle イベントを追加します。HTMLDetailsElement.open プロパティは、open HTML 属性を反映するブール値です。要素のコンテンツ(<summary> を除く)をユーザーに表示するかどうかを示します。切り替えイベントは、<details> 要素が開閉されたときに発生します。このイベントをリッスンするには、addEventListener() を使用します。

ユーザーが別の詳細を開いたときに開いている詳細を閉じるスクリプトを作成する場合は、removeAttribute("open") を使用して open 属性を削除します。

これは JavaScript を使用する唯一の例です。他の開いているウィジェットを閉じる場合を除き、JavaScript は必要ありません。

<details><summary> はスタイルを大幅に変更でき、ツールチップの作成にも使用できます。ただし、ネイティブのセマンティクスが一致しないユースケースでこれらのセマンティック要素を使用する場合は、必ずアクセシビリティを維持してください。HTML は、ほとんどの場合、デフォルトでアクセス可能です。開発者の仕事は、コンテンツにアクセスできるようにすることです。

理解度を確認する

詳細と概要に関する知識をテストします。

<summary> はどの要素の最初の子要素でなければなりませんか?

<p>
もう一度お試しください。
<details>
正解です。
<fieldset>
もう一度お試しください。