みかづきブログ・カスタム

基本的にはちょちょいのほいです。

details要素のopen属性の有無でプロパティを変化させる際、transitionを設定してもアニメーションしない 😱

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の挙動なのかは切り分けできていません。また、仕様通りなのかバグなのかもいまのところ不明です。