Front End Programming

CSS3 だけでアコーディオンメニューを実装

CSS CSSアニメーション

CSS3 のアニメーションのおかげで、jQuery のアニメーションにあまり頼らなくても気軽にアニメーションを実装できるようになりました。
アコーディオンメニューなどでありがちな、スライドアニメーションを実装する方法をご紹介します。

JS でクラスを付与して状態を操作

jQuery のアニメーションを使わずにアニメーションを実装する時、クラスなどで操作するのがベストではないでしょうか。

私はよく、例えばこんな感じでクリックした時にクラスを付与して状態を操作します。

クラス opend がメニューに付与された際に高さを操作すれば簡単にアコーディオンメニューができます。

 

バニラJS でも簡単に書けますね。

//ボタン、メニューの取得
const btn = document.getElementById('button')
const menu = document.getElementById('menu')

//クリックした時の挙動
btn.addEventListener('click',()=>{
  //menuの状態を判定し、クラスを付与
  if(menu.getAttribute('class') === 'opened'){
    menu.removeAttribute('class')
  }else{
    menu.setAttribute('class','opened')
  }
})

CSSプロパティの height ではなく max-height を使おう

なんでheightじゃダメなの?

height を使う場合はコンテンツがいっぱいになった時の高さを指定しておけばアニメーションします。

 

/* 閉じているとき */
#menu {
  height: 0;
  transition: .5s;
}

/* 開いている時 */
#menu.opened {
  height: 100px;
}

ところがどっこい、メニューの高さなんてコンテンツ幅で変わることもあるし、必ず指定できるとは限りません。

と、なると height: auto;を指定したくなっちゃいます。こうなるとアニメーションがどうにも動かなくなってしまいます。

/* 閉じているとき */
#menu {
  height: 0;
  transition: .5s;
}

/* 開いている時 */
#menu.opened {
  height: auto;
}

max-height で大抵解決

メニューの高さがブラウザを確実に超えない場合は以下で大抵解決します。

両方に値が入っているので、きちんとアニメーションしてくれます。

/* 閉じているとき */
#menu {
  max-height: 0;
  transition: .5s;
}

/* 開いている時 */
#menu.opened {
  max-height: 100vh;
}

accordion-menu 1

難点は、コンテンツの高さによってアニメーションのスピードにばらつきが出ることですかね。

もっと汎用的なメニューを作りたいならもう JS と合わせ技を使った方が良さそうですね。

まとめ

こういったメニューは簡易的ですし、アレンジが効くのででよく使います。

最後までお読みいただきありがとうござます。

関連記事もあわせてお読みください

Read More

記事のジャンル

管理人について

私、フロントエンドエンジニアのかみーゆです。日本でフロントエンドを中心に10年以上Web制作 →→→ セブ島に転職してエンジニア講師 →→→ オフショア開発担当者(イマココ)。13歳の頃から「好きなように生きて好きなように死ぬ」が人生のKPI。なので、「楽しいか」、「かっこいいか」でやることを判断・取捨択一しています。好きなものは肉とビール。

About Me