[Nuxt.js][TailwindCSS] レスポンシブなナビゲーションメニューを作る

公開日:2024-06-21
最終更新日:2024-06-21

Nuxt.js

TailwindCSS

TypeScript

概要

  • PC版とモバイル版でナビゲーションメニューの表示を切り替えたい
  • Nuxt.js v3とTailwindCSSを使ったレスポンシブなナビゲーションメニューを作る

という話。

はじめに

SEO的なアレは忘れるとして(大事なんだけど)、メニューの表示をPC版とモバイル版で変えたいってのはよくあるじゃないですか?
PC版だとグローバルナビゲーションメニューとしてヘッダーにずらずら並べて、モバイル版はハンバーガーメニューにするアレです。

TailwindCSSでレスポンシブなメニューの実装をググると情報としてたくさん出てくるのがReact.js系が多くて、Nuxt.jsだとそこまで多くないのかなーという印象だったので作りました。

ま、自分がReact好きじゃないからっていうのが1番なんですけどね。

とりあえず完成品

StackBlitzに完成品のコードを置いておきます。
解説とか面倒臭いって人はこちらだけどうぞ。

https://stackblitz.com/edit/nuxt-tailwind-responsive-navbar

ほな中身の話でもしようか

ざっくり概要

はじめに書いた通りではありますが、PC版のレイアウトではヘッダー部分にグローバルナビゲーションとしてメニューがずらずら並びます。
こんな感じ。

モバイル版ではグローバルナビゲーションが非表示になり、ハンバーガーメニューになります。
こんな感じ。

グローバルナビゲーションメニュー

PC版のグローバルナビゲーションメニューの実装は以下になります。

<template>
  <!-- 省略 -->
  
  <nav class="hidden lg:block">
    <ul class="flex space-x-8 text-xl text-white ">
      <li>
        <span class="hover:underline hover:decoration-1">Home</span>
      </li>
      <li>
        <span class="hover:underline hover:decoration-1">Get started</span>
      </li>
      <li>
        <span class="hover:underline hover:decoration-1">Modules</span>
      </li>
      <li>
        <span class="hover:underline hover:decoration-1">Examples</span>
      </li>
    </ul>
  </nav>
  
  <!-- 省略 -->
</template>

まぁよくあるやつですね、 <nav> タグで囲んで <ul> / <li> をFlex Boxにして横並びにしてるだけです。

ただTailwindはモバイルファーストのコンセプトなので、デフォルトとして hidden のクラスをつけています。
で、これはPC版では表示していきたいので lg:block としています。

ハンバーガーメニュー

モバイル版のハンバーガーメニューの実装は以下になります。

<template>
  <button
    type="button"
    class="lg:hidden"
    @click="isDrawerOpen = true"
  >
    <img src="~/assets/img/bars-solid.svg" class="h-8 w-8"></img>
  </button>

  <!-- drawer menu (for mobile) -->
  <aside
    class="bg-[#020420] fixed top-0 left-0 w-full h-full z-30 p-8 ease-in-out transition-all duration-300"
    :class="isDrawerOpen ? 'translate-x-0' : '-translate-x-full'"
  >
    <div class="flex justify-end">
      <button
        type="button"
        @click="isDrawerOpen = false"
      >
        <img src="~/assets/img/xmark-solid.svg" class="h-8 w-8"></img>
      </button>
    </div>

    <ul class="flex flex-col items-center space-y-6 text-xl text-white">
      <li @click="isDrawerOpen = false">
        <span class="hover:underline hover:decoration-1">Home</span>
      </li>
      <li @click="isDrawerOpen = false">
        <span class="hover:underline hover:decoration-1">Get started</span>
      </li>
      <li @click="isDrawerOpen = false">
        <span class="hover:underline hover:decoration-1">Modules</span>
      </li>
      <li @click="isDrawerOpen = false">
        <span class="hover:underline hover:decoration-1">Examples</span>
      </li>
    </ul>
  </aside>
</template>

<script setup lang="ts">
const isDrawerOpen = ref<boolean>(false)
</script>

画面左からスライドインしてくるdrawerメニューの状態を管理するために、 isDrawerOpen のフラグだけ用意しましょう。

あとはハンバーガーメニューとしてボタンを設置し、ボタンがクリックされたら isDrawerOpen をtrueにしてメニューをスライドインさせてくると。

言わずもがなハンバーガーメニューでの表示はモバイル向けなので縦並びにしておきましょう。

isDrawerOpen の値に応じてTailwindのアニメーション系のクラスを切り替えることで、メニューの開閉動作を行います。
Tailwindはこの辺のアニメーションも色んなクラスが用意されているので便利ですね。

isDrawerOpen がfalseの場合は -translate-x-full とすることで、X軸のマイナス方向100%を意味するので画面の左外に待機、または出ていく動きになります。
isDrawerOpen がtrueの場合は translate-x-0 とすることで、X軸方向の0位置を意味するのでメニューの左端が画面の左端(x = 0)に出てくる動きになるわけですね。

まとめ

ハンバーガーメニューはSEO的にアレだっていうのは分かってはいるんですが、ただ昨今のWebレイアウトでよく見るものなので作ってみました。
実装するにあたってこちらのサンプルがとても分かりやすかったので参考にさせてもらいました(だいぶコピペさせてもらったけど)。

Nuxt-Tailwind-Responsive-Navbar

これからはモバイル向けのメニューはボトムナビゲーションなんかが主流になっていくんですかね、知らんけど。

©︎ s-kugel All Rights Reserved.