transitionでheight:autoを動かす2つの方法。
2024/12/20 (金) - 09:00 CSSJavaScript
アコーディオンメニューをCSSで実装する際、height:0
からheight:auto
にすることで開閉はしますがトランジションは動きません。それを解決するためにmax-height
を使うテクニックやjQueryのslideToggle
を使うことが多かったと思いますが、どうもしっくりこない。今回はそれを暫定的に解決する方法を見つけたので紹介します。
HTMLは以下。dtをタップしたら閉じているdd要素を開閉するようにします。
<dl>
<dt>レシピを見る</dt>
<dd><ul>
<li>パスタ:200グラム</li>
<li>キャベツ:1〜2枚</li>
<li>...</li>
<li>にんにく:1欠</li>
<li>オリーブオイル:大さじ2</li>
<li>塩コショウ:適量</li>
</ul></dd>
</dl>
JavaScriptは以下のように、dt要素をタップした時dt要素自体にclass属性を付けて見た目の動きはCSSで処理するようにします。
const toggleBtn = document.getElementsByTagName('dt');
for (let dt of toggleBtn) {
dt.addEventListener('click',function(e){
this.classList.toggle('toggleOn');
e.preventDefault();
},false);
}
こちらではdtをタップしたら自分自身に、classList.toggle
でtoggleOn
というclass属性値を追加・削除します。
1.gridを使うパターン
少しハックっぽいですが、gridで行の高さを指定するgrid-template-rows
プロパティで指定する方法です。最初は0fr
で隠しておき、開くときはで1fr
に切り替えるというものです。実はtransition
が有効なんですね。こちらはgridが使えるブラウザであれば動きます。
dt{
cursor: pointer;
}
dd{
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.25s;
}
.toggleOn+dd {
grid-template-rows: 1fr;
}
ul {
overflow-y: hidden;
}
2.interpolate-sizeを使うパターン
dd要素にinterpolate-size: allow-keywords;
というCSSプロパティを付与し、height: 0;
とoverflow: hidden;
で隠しておきます。dtをタップしたらddにheight: auto;
の値を付与するとtransition
でauto
の高さまでトランジションが動きます。このinterpolate-size: allow-keywords;
を指定すると、auto/min-content/max-content
といったキーワード系の値に対しても数値が有効になりトランジションが動作します。
dt{
cursor: pointer;
}
dd{
interpolate-size: allow-keywords;
height: 0;
transition: height 0.25s;
overflow: hidden;
}
.toggleOn+dd {
height: auto;
}
非常にシンプルでわかりやすいと思いますが、2024年12月時点ではChrome 129および、Android Chrome 131以降のみ対応しており、SafariやFirefoxでは未対応です。未対応ブラウザではトランジションしないだけでプログレッシブエンハンスメントとして動きはするので問題はありませんが、すべてのブラウザでトランジションさせたい場合はgridを採用するか従来通りmax-heightのテクを採用するのが良さそうです。
参考ページ
- Web制作者の念願がついに叶った! height: 0;からheight: auto;へのトランジションをJavaScriptは無し、CSSで実装する方法
- CSS – interpolate-size – とほほのWWW入門
- CSS property: interpolate-size | Can I use… Support tables for HTML5, CSS3, etc
おしまい♥
おすすめ記事
- Next.js[App Router]&microCMSでRSSフィードを実装する
- JavaScriptで雪を降らせる
- JavaScript(VanillaJS)でDOM要素を指定するには
- CSSだけで簡易的にimg要素の画像をダウンロード禁止にさせる
- microCMS&Astroで記事のページネーションを実装
トラックバック & ピンバック
- この記事へのトラックバックURI:
- https://weblog.walk-life.me/transition_auto/trackback/