details要素自体をアニメーションさせる場合
details要素自体にtransitionを設定し、open属性の有無でプロパティを変化させたときはアニメーションします。
※ Google Chrome(123.0.6312.124)でしか確認していません。
DEMO
SCSS
details { background: rgba(255, 0, 0, .2); transition: background .2s ease-in-out; // 効果あり &[open] { background: rgba(0, 255, 0, .2); } }
details要素の子要素をアニメーションさせる場合
details要素の子要素にtransitionを設定し、open属性の有無でプロパティを変化させたときはアニメーションしません。
※ Google Chrome(123.0.6312.124)でのみ確認
DEMO
borderはdetails要素に設定しているのでアニメーションしますが、背景色は子要素に設定しているのでアニメーションしません。
SCSS
details { border: solid rgba(255, 0, 0, .2); transition: border .2s ease-in-out; p { background: rgba(255, 0, 0, .2); transition: background .2s ease-in-out; } &[open] { border: solid rgba(0, 255, 0, .2); p { background: rgba(0, 255, 0, .2); } } }
子要素をアニメーションさせたい場合は、open属性の代わりとなるものをJavaScriptで設定すればアニメーションするようになります。
※ Google Chrome(123.0.6312.124)でのみ確認
DEMO
SCSS
<details data-is-open="false"> <summary>サマリー</summary> <p>ディスクリプション</p> </details>
details { border: solid rgba(255, 0, 0, .2); transition: border .2s ease-in-out; p { background: rgba(255, 0, 0, .2); transition: background .2s ease-in-out; } &[data-is-open='true'] { border: solid rgba(0, 255, 0, .2); p { background: rgba(0, 255, 0, .2); } } }
JavaScript
const details = document.querySelector('[data-is-open]'); const duration = 200; details.addEventListener('click', (evt) => { if (details.open) { details.dataset.isOpen = false; } else { setTimeout(() => { details.dataset.isOpen = true; }, duration / 2); } });
data-is-openにopen属性の値を設定します。
開く際はワンテンポ遅らせてから設定しないと、うまくアニメーションしません。
くどいようですが、Google Chrome(123.0.6312.124)でしか確認していないので、details要素の挙動なのか、Chromeの挙動なのかは切り分けできていません。また、仕様通りなのかバグなのかもいまのところ不明です。