📗

CSS変数でmax-heightを使ったアコーディオンを作る

2021/12/11に公開

JavaScriptで開閉するアコーディオンを作る時、高さのアニメーションをtransitionで指定する場合、max-heightを使う方法があります。
参考
https://qiita.com/harada-k/items/30c01e473d2e417121f5

この方法では、アコーディオンの中身の高さが不明な場合を想定して、 9999px など十分すぎる数値を指定しておくのですが、なんか大きすぎる数値嫌だなと思い、カスタム変数を使った方法をやってみました。

以下のURLのサンプルコードをクリックで開閉するアコーディオンに書き換えたものです
https://www.30secondsofcode.org/css/s/height-transition

デモ

実装方法

CSSのポイントはここです。開いた時のmax-heightはカスタムプロパティで指定しています。

/* Accordion Style */
.content {
  transition: max-height 0.3s;
  overflow: hidden;
  max-height: 0;
}

.content.is-open {
  max-height: var(--max-height);
}

JSのポイントはここ。それぞれのアコーディオンのコンテンツ部分の高さを取得し、カスタムプロパティとして指定しておきます。

content.forEach((el, index) => {
  const height = el.scrollHeight;
  el.style.setProperty("--max-height", height + "px");
});

あとは、JSでクリックしたタイミングで is-open を付け外しすれば、カスタムプロパティのmax-heighの数値が適用されたり、されなかったりして、開閉することができます。

これをカスタムプロパティを使わず、JavaScriptでやろうとすると以下のようにクリック時に高さを取得したりすると思いますが、カスタムプロパティを使った方法だと開閉のJSはすごくシンプルになります。

  1. トリガーをクリック
  2. そのトリガーに関するコンテンツの高さを取得
  3. コンテンツにJSで高さを指定
  4. 閉じるときはまたJSで高さ0にする

注意点

サンプルのコードは読み込んだ時に高さを指定するので、リサイズ時に再度max-heightを指定しなおす必要あると思います。

Discussion