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