公開日: 2024 年 11 月 6 日
Chrome 131 以降では、<details>
要素と <summary>
要素の構造のスタイル設定を行うためのオプションが増えました。これらの要素は、開示ウィジェットやアコーディオン ウィジェットを作成する際に使用できます。
具体的には、Chrome 131 で導入された変更により、これらの要素で display
プロパティを使用できるようになり、展開と折りたたみの部分にスタイルを設定する ::details-content
疑似要素が追加されました。
<details>
要素に display
を設定する
これまで、<details>
要素の表示タイプを変更することはできませんでした。この制限が緩和され、たとえば <details>
要素でグリッド レイアウトやフレックス レイアウトを使用できるようになりました。
次の例では、排他的アコーディオンは、横に並べられた複数の <details>
要素で構成されています。<details>
要素の 1 つを展開すると、そのコンテンツが <summary>
の横に配置されます。
デモ
録画中
これは、次の CSS を使用して <details>
要素にフレックス レイアウトを使用することで実現されます。
details {
display: flex;
flex-direction: row;
}
grid
などの他の表示値も使用できます。
display: inline
の使用に関する注意事項
予期しない結果になる可能性がある display
値は inline
です。機能しないのではなく、HTML パーサーの制限によるものです。
段落内に <details>
要素を配置すると、HTML 標準のセクション 13.2.6.4.7 で定義されているように、HTML パーサーはまず開いている段落を閉じます。
タグ名が「address」、「article」、「aside」、「blockquote」、「center」、「details」、「dialog」、「dir」、「div」、「dl」、「fieldset」、「figcaption」、「figure」、「footer」、「header」、「hgroup」、「main」、「menu」、「nav」、「ol」、「p」、「search」、「section」、「summary」、「ul」のいずれかである開始タグ
開いている要素のスタックにボタン スコープの p 要素がある場合は、p 要素を閉じます。トークンの HTML 要素を挿入します。
その結果、display: inline
を設定していても、<details>
はブロック方向に流れます。
たとえば、次のマークアップ
<p>Hello <details>…</details> world</p>
解析後:
<p>Hello </p><details>…</details> world<p></p>
こちらのデモで、Chrome DevTools を使用して解析されたマークアップを検査すると、ご自身で確認できます。
これは、<p>
内の <details>
のネストにのみ適用されます。<div>
内の <details>
で display: inline
を使用しても問題ありません。
::details-content
疑似
ブラウザでは、<details>
要素は Shadow DOM を使用して実装されます。概要用の <slot>
(デフォルトの概要子を含む)と、残りのすべてのコンテンツ用の <slot>
(<summary>
要素を除く <details>
要素のすべての子)が含まれます。
<details>
↳ #shadow-root (user-agent)
<slot id="details-summary">
<summary>Details</summary>
<!-- The summary goes here -->
</slot>
<slot id="details-content">
<!-- All content goes here -->
</slot>
</details>
<details>
でより多くの表示タイプを使用できるだけでなく、::details-content
疑似要素を使用してコンテンツ スロットをターゲットにできるようになりました。この疑似クラスを使用して、<details>
要素のコンテンツをラップするコンテナのスタイルを設定できます。
details::details-content {
border: 5px dashed hotpink;
}
<details>
要素が開いている場合にのみ設定されたスタイルを適用するには、[open]
セレクタを先頭に追加します。
[open]::details-content {
border: 5px dashed hotpink;
}
<details>
要素が [open]
状態の場合にのみ、::details-content
疑似クラスにスタイルを適用することをおすすめします。
デモ
録画中
::details-content
の display
型は UA スタイルシートで block
に設定されています。以前は display: contents
でした。この変更は、height: 100%
に依存する開示されたコンテンツなど、場合によっては不利になる可能性があります。これが問題になる場合は、次のように display
型を contents
に戻すことで回避できます。details[open]::details-content { display: contents; }
::details-content
疑似要素をアニメーション化する
<details>
要素のコンテンツを、展開時にアニメーション化できます。次の例では、幅が 0px
から 300px
にアニメーションします。
::details-content {
transition: width 0.5s ease, content-visibility 0.5s ease allow-discrete;
width: 0;
}
[open]::details-content {
width: 300px;
}
width
の移行に加えて、content-visibility
プロパティも移行する必要があります。これは、User-Agent スタイルシートで定義されているように、その値が開いていない状態と開いている状態の間で変化するためです。このプロパティは個別にアニメーション化可能なプロパティであるため、機能させるには allow-discrete
キーワードが必要です。
前に共有した排他的アコーディオンのデモに追加すると、次のようになります。
デモ
録画中
height
はアニメーション化することもできます。height: auto
にアニメーションするには、interpolate-size
または calc-size()
を使用する必要があります。また、コンテンツが ::details-content
疑似要素から漏れ出さないように、overflow: clip
を適用します。
::details-content {
transition: height 0.5s ease, content-visibility 0.5s ease allow-discrete;
height: 0;
overflow: clip;
}
/* Browser supports interpolate-size */
@supports (interpolate-size: allow-keywords) {
:root {
interpolate-size: allow-keywords;
}
[open]::details-content {
height: auto;
}
}
/* Fallback for browsers with no interpolate-size support */
@supports not (interpolate-size: allow-keywords) {
[open]::details-content {
height: 150px;
overflow-y: scroll; /* In case the contents should be taller than 150px */
}
}
次のデモ(Material UI のアコーディオンにインスピレーションを得たもの)で、コードの動作を確認できます。各 <details>
要素の内容がスムーズにアニメーション表示されます。
デモ
録画中
::details-content
をサポートしていないブラウザでも、コンポーネントは正常に動作します。アニメーションは表示されません。
特徴検出
CSS で ::details-content
疑似クラスのサポートを検出するには、次のスニペットを使用します。
@supports selector(::details-content) {
…
}
この検出を、サイト訪問者が使用しているブラウザが追加の表示値をサポートしているかどうかを判断するためのチェックとして使用することもできます。
ユーザー補助に関する考慮事項
::details-content
疑似要素の導入と表示タイプの変更機能は、<details>
要素のアクセシビリティに影響しません。
以前と同様に、少なくとも Chromium ベースのブラウザと HTML 標準では、<details>
要素は検索可能であり、ブラウザがページ内検索、ScrollToTextFragment、要素フラグメント ナビゲーションに応じて非表示のコンテンツにスクロールしようとすると、自動的に展開されます。これは変更されません。
ただし、排他的アコーディオンを使用する前に、ユーザーにとって有益か有害かを検討してください。排他的なアコーディオンを使用すると、コンテンツが占める視覚的なスペースは減りますが、ユーザーはすべての情報を確認するために多くの項目を開く必要が生じる可能性があります。複数のアイテムを同時に確認したいユーザーにとっては不便です。
マーカーのスタイル設定はどうすればよいですか?
現在、リストマーカーのスタイル設定は相互運用できません。Gecko と(現在の)Chromium で採用されているアプローチと、WebKit で採用されているアプローチ(以前は Chromium と共有)の 2 つがあるためです。
相互運用が可能になったら、マーカーのスタイル設定をより細かく制御できるようにする予定です。
その他のデモ
最後に、その他のデモをいくつかご紹介します。これらはすべて ::details-content
を使用します。
UIKit アコーディオン
デモ
録画中
このデモは UIKit アコーディオンをベースにしています。コードは、以前に共有した Material UI アコーディオンとほぼ同じです。
一部開いた開示ウィジェット
デモ
録画中
このデモでは、コンテンツがすでに画面に表示されている開いた状態の開示ウィジェットが使用されています。このため、content-visibility
は常に visible
に設定されます。height
は、計算が伴うため、calc-size()
を使用してアニメーション化されます。
::details-content {
content-visibility: visible; /* Make it always visible */
transition: height 0.5s ease;
height: 150px;
overflow: clip;
}
[open]::details-content {
height: calc-size(auto, size + 0.5rem); /* calc-size because we need to add a length */
}
スタイリングの便宜上、コンテンツはラッパー div でラップされます。ラッパー div には padding
などのレイアウト スタイルが適用され、::details-content
疑似要素がアニメーション化されます。