height: auto;なアコーディオンメニューの作り方

ABOUTこの記事をかいた人

フロントエンドエンジニア。

はい、今回はアコーディオンメニューについてです。
このメニューはwebデザインにおいて採用されることが多く、実装の機会も多くなります。

そこで良く出会うのが、「height: auto;にアニメーションが効かない」問題です。コーダーをやっている方なら1度はこの問題に出会うのではないでしょうか。

そんなheight: auto;なアコーディオンメニューをスマートに作る方法を紹介します。

基本的なアコーディオンメニューの作り方はこちらから。また、この記事のコードも以下の記事と同様のリセットCSS(https://github.com/nicolas-cusan/destyle.css/blob/master/destyle.css)を導入している前提で解説します。

【徹底解説】5歳でも分かる、アコーディオンメニューの作り方(jQuery編)

2021年10月20日

目次

結論

解説が長くなるので、まずは最終的なコードを載せます。

index.html
style.css

解説

実装方針|一旦数値を挟んでからautoにする

早速作っていきましょう。見た目はこんな感じとします。

各メニュー項目のラベルをクリックして開閉する形です。

HTML/CSS部分は以下の通りです。

構造としてはメニューがあって、その中にメニューの各項目を配置します。

各項目はそれぞれ見出しとコンテンツを持ちます。

ポイントはコンテンツ部分が2重構造になっていることで、外側(.Menu-Item__Inner)が高さ0になっていることにより初期状態で余白も含めてコンテンツを見せないようにしています。

さて、次の発想として.Menu-Item__Innerの高さを0とautoで切り替わるようにするやり方ですが、単純に切り替えるだけでは想定の動きになりません。例えば以下のようなコードになるでしょう。

付け替え用のクラスと、それを操作するスクリプトを用意します。今回はjQueryを用います。

.Menu-Item__Innerにはきちんとtransitionの設定をしているにもかかわらず、アニメーションをせずに切り替わってしまいます(試してみてください)。

冒頭でも書いた通り、autoへのtransitionは効かないからです。

widthやheightのtransitionは基本的に数値→数値でないとうまく動きません。しかし、こういったメニューで高さが数値指定であることは実務ではあまりないのではないでしょうか。

そこで見出しにも書いたように、一旦数値を挟んでからアニメーションさせ、その後に高さをautoにするという手順を踏みましょう。

具体的には、メニューを開くときは

0→(アニメーション)→コンテンツの高さ→auto

メニューを閉じるときは

auto→コンテンツの高さ→(アニメーション)→0

というような変化をするようにしていきます。

アニメーション実装

まず、メニュー開閉状態をどこかに保持した方が都合が良いです。今回はdata属性を用いましょう。

各メニューのラベル部分(Menu-Item-Label)にdata-is-openという属性を付与します。値はfalseです。

jQueryからは、この値がfalseであればメニューを開く処理を行い、trueの時に閉じる処理を行います。

メニューの開閉は先述の通りheightを変更するわけですが、コンテンツの高さはどのように取得すれば良いでしょうか。

今回のコードでは、コンテンツ部分を2重にしており外側(.Menu-Item__Inner)の高さを0にしているため内側(.Menu-Item-Content)の高さは残っています。これを使いましょう。

まずはメニューを開く処理から。

そしてメニューを開くアニメーションが終わるタイングでheightをautoにし、data属性の値を変更します。

閉じる場合の処理は以下の形です。autoになっている高さを一旦数値に置き換えてから、一瞬遅らせて高さを0にします。

これでheight: auto;なアコーディオンメニューができました。

まとめ

ということで、height: auto;なアコーディオンメニューでした。

height: 0; とheight: auto; の変化をさせる際に一旦数値を挟むことがポイントでした。この点さえ押さえれば今回以外の書き方でも実現可能なので、環境に合わせてお試しください。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください