heightやmax-heightでtransitionを効かせるには、heightを厳密に指定しないといけない 。
(height: autoやheight: fit-contentではtransitionが効かないため)
とはいえ、要素によって高さが異なると、1つ1つCSSで指定するのは煩雑。
かつ、柔軟性・保守性が悪い。
そんなときは、JSで高さを算出し、CSSに渡す対応が良い。
目次
高さを算出して、その値をCSSに渡すJavaScriptコード
コード例
window.addEventListener('load', addHeightProperty);
window.addEventListener('resize', addHeightProperty);
function addHeightProperty() {
const targetElms = document.querySelectorAll('.js-height-property');
targetElms.forEach((target) => {
const targetHeight = target.scrollHeight;
target.style.setProperty('--content-height', targetHeight+'px');
});
}
※余談だが、アロー関数で書く場合は、関数の定義が先になければならない。
(イベントリスナーの登録は関数より後ろ)
コードの解説
.js-height-propertyクラスを持つ要素に対し、その要素の高さ(scrollHeight)をstyle.setProperty()でスタイル付与する。(style属性をつける)
直接sytleを付与するのではなく、カスタムプロパティを付与するのがポイント。
上記コード例の場合、このようなstyle属性が付く
<div class="js-height-property" style="--content-height: 301px;">
・・・
</div>
scrollHeightで高さを求めている理由は、scrollHeightなら要素が非表示(height: 0やmax-height: 0)でも、本来の高さを求められるから。
もしscrollHeightを使えないのであれば、下記のコードのように一時的に要素を表示して高さを取得すると良い。
target.style.height = 'auto';//一時的に表示(style属性でheight: auto付与)
targetHeight = target.clientHeight;//高さを取得
target.removeAttribute('style');//一時的に表示するためのstyle属性を削除
渡された値をCSSで参照
JavaScriptで付与したカスタムプロパティを使ってheightを設定する。
コード例
.hoge{
max-height: 0;
transition: max-height 0.3s ease;
&.is-open{
max-height: var(--content-height);
}
}
コメント