CSSのheightプロパティを 0px → auto(もしくはその逆の auto → 0px)へtransitionでアニメーションさせたいが、height:autoを使うと動作しないという問題がある。
これはアコーディオンを実装する時にだれしもがぶち当たる問題として有名ですが、それでもなんとかCSSだけでごまかす方法はないだろうか、というのを考えてみました。
(※ 「CSSだけ」 = JS はクラスの付け外しだけ という意。)
今回例として紹介するコードはあくまで動作部分のみを書いており、アクセシビリティなどの配慮はゼロなので実案件にコピーして使ったりはしないでください
paddingをアニメーションしてごまかす
アコーディオンコンテンツの上下にpaddingをセットしておき、そのpadding-top,paddinf-bottomをクローズ時に0pxへtransitionさせる方法です。
See the Pen height 0⇆auto ごまかし案A by ddryo (@ddryo-the-encoder) on CodePen.
どうでしょう、これ結構良くないですか?
よく見ると、コンテンツの高さ自体は一瞬で切り替わってるのですが、上下のpadding部分がニューっと動いている(出現時はさらにopacityの transitionもある)ので、全体がアニメーションできているように見えます。
transitionの時間を長めにしてゆっくり動かすとごまかせなくなってきますが、.25s
くらいだとこれで十分だと思います。
これは僕自身「あれ、heightのtransition動くようになってるじゃん」と勘違いしたまましばらく気づいてなかった方法なので、人によってはほとんど違和感ないと思います。
フェードインだけでごまかす
次は、「開く・閉じる」動きに関するアニメーションは潔く諦め、開く時に中身だけ良い感じにフェードインさせてごまかしてみました。
See the Pen height 0⇆auto ごまかし案B by ddryo (@ddryo-the-encoder) on CodePen.
これもなかなかいいですね。
ただコンテンツ部分にインナーを一層挟まないといけないことだけが個人的にはちょっと気になります。(中身の要素全部に対してアニメーションつければインナーいらないけど...)
※ 閉じる時も同じようにアニメーション付けてみたのですが(コメントアウトしてるコードがそれです)、JSもCSSもコードが増える割には挙動が気持ち悪かったので、閉じるときは潔くスパッと閉じるのが良さそうです。
そもそも...そのアニメーション、いる?
そんな元も子もないことを言うんじゃないよって感じですが、「そもそも動きを付ける必要、あるのかな?」というのは一度考えてみてもいいかもしれません。
正直、なくていいと思います。なんなら無駄な動きがない方が良い印象を与えれることもあります。
(それでも僕は基本的には付けたい派。かつ、JSは長々と書きたくない派)
アコーディオンに限らず、製作者側としてはついつい色々と動きをつけて行きたくなりますが、それは本当に必要なのかどうか?というのは定期的に立ち止まって自問自答していきたいところです。