Next.js+BULMAでアニメーション付きハンバーガーメニューを作る

## やりたいこと
* [BULMA](https://bulma.io/)は非常に軽量で扱いやすく、拡張性が高いCSSフレームワークです。

https://bulma.io/

* 今回は、Next.jsで作ったサイトに、BULMAを導入し、ハンバーガーメニューを作って、そこにアニメーションを付ける、というのをやってみました🍔
* 完成したものはこちら👇

![animated-hamburger.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1309306/c913692d-d28a-ee55-a1b5-c14a7131a227.gif)


## BULMAの導入
* 今回は、CDNから参照して使っています。
* htmlの``<Head>``タグ内に、BULMAを使うためのリンクを追加します。
* fontawesomeを使っているのでそのためのリンクも追加しています。

```html:components/layout.tsx
<Head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css" />
  <link rel="stylesheet" href="https://bulma.io/vendor/fontawesome-free-5.15.2-web/css/all.min.css" />
</Head>
```

## NavBarコンポーネントを作る

* **components/NavBar.tsx**を作り、**components/layout.tsx**で呼び出しています。
* [Navbar | BULMA](https://bulma.io/documentation/components/navbar/)のドキュメントからコピペして作りました。

```js:components/NavBar.tsx
import React, { useState } from 'react'

export default function NavBar() {
  const [openMenu, setOpenMenu] = useState('')
  const toggleMenu = () => openMenu === 'is-active' ? setOpenMenu('') : setOpenMenu('is-active')

  return (
    <nav className="navbar" role="navigation" aria-label="main navigation">
      <div className="container">
        <div className="navbar-brand">
          <a role="button" className={`navbar-burger ${openMenu}`}aria-label="menu" aria-expanded="false" data-target="navbarBasicExample" onClick={toggleMenu}>
            <span aria-hidden="true"></span>
            <span aria-hidden="true"></span>
            <span aria-hidden="true"></span>
          </a>
        </div>
        <div id="navbarBasicExample" className={`navbar-menu ${openMenu}`}>
          // 省略（ここにメニューを配置する）
        </div>
      </div>
    </nav>
  )
}
```

### 🌟ポイント
  1. ``const [openMenu, setOpenMenu] = useState('')``でtoggleMenuの初期値を設定
  1. ``toggleMenu``はハンバーガーメニューの開閉をtoggleするfunction
  1. ``className={`navbar-burger ${openMenu}`}``で、ハンバーガーメニューの開閉時のCSSを設定する要素判別の為のクラスを``openMenu``という変数に格納し、付与しています
  1. ``className={`navbar-menu ${openMenu}`}``も同様です


* ここまでやれば、ハンバーガーメニューの開閉は可能になります。
* 開閉時のアニメーションを付けたい場合は、下記のCSSを足す必要があります。


## メニュー開閉にアニメーションを付ける
* **styles/global.css**に下記のソースを足す

```css:styles/global.css
.navbar {
  position: sticky;
  top: 0;
  min-height: 3.5rem;
}
.navbar-brand {
  min-height: 3.5rem;
}

@media screen and (max-width:1023px) {
  html,
  body {
    font-size: 82.5%;
  }
  .navbar-menu {
    width: 3.5rem;
    top: 0rem;
    opacity: 0;
    transition: all 0.3s;
    display: block;
    z-index: -1;
    position: absolute;
    width: 100%
    pointer-events: none;
  }
  .navbar-menu.is-active {
    transform:translateY(3.5rem);
    opacity: 1;
    z-index: 10;
    pointer-events: auto;
  }
  .navbar-burger {
    height: 3.5rem;
    width: 3.5rem
  }
}

```

### 🌟ポイント
1. ``z-index: -1;``で非表示、``z-index: 10;``で表示にしています
1. ``opacity: 0;``と``opacity: 1;``は、ふわっと表示/非表示されるようにするために指定
1. ``transform:translateY(3.5rem);``は、上から降りてくるようにするために指定
1. ``opacity: 0;``の場合、リンクは消えないので押せてしまう。なので、``pointer-events: auto;``と``pointer-events: none;``で、メニューが非表示の場合にメニューのリンクをクリックできないようにしています。

* ``.navbar``の``position: sticky;``と``top: 0;``は、Navbarを固定するために指定しているので、不要な場合は削除する
* その他は配置を整えるために指定しています

## 感想
* BULMAはクラスを指定するだけでページをかなり綺麗に整えることができます。余計なものがついていないので、アニメーションなど自分で好きなように付けられるのが良いなと感じました。
* ちなみにページ遷移にはFramer motionでアニメーションを付けています。が、ちょっと複雑でまだ全然理解が追いついていないので、BULMAくらいシンプルなのは本当に助かります。

####　プレビューはこちらのサイトで可能です
* ポートフォリオサイトにしたいけどただの実験場でしかないページです😂

https://www.erikoono.com/