🌛

Nuxt 3 + Tailwind CSS でダークモードを実装する

2022/12/22に公開

はじめに

Nuxt 3 と Tailwind CSS を使ってダークモードを実装する流れを備忘録として記事にまとめました。

Nuxt 3 インストール

公式ドキュメントを参考にインストールします。

npx nuxi init darkmode-sample
cd darkmode-sample
npm install
npm run dev

指定された localhost にアクセスすると Welcome ページが表示されました。

Tailwind CSS セットアップ

インストール

こちらも公式ドキュメントを参考にインストールします。

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init

nuxt.config に追記

nuxt.config.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
+ postcss: {
+   plugins: {
+     tailwindcss: {},
+     autoprefixer: {},
+   },
+ },
})

tailwind.config に追記

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
+   content: [
+       "./components/**/*.{js,vue,ts}",
+       "./layouts/**/*.vue",
+       "./pages/**/*.vue",
+       "./plugins/**/*.{js,ts}",
+       "./nuxt.config.{js,ts}",
+       "./app.vue",
+   ],
    theme: {
        extend: {},
    },
    plugins: [],
}

main.css 作成

./assets/css/main.cssを作成して main.css の中に下記コードを記述します。

main.css
@tailwind base;
@tailwind components;
@tailwind utilities;

作成した main.css を nuxt.config で読み込む

nuxt.config.ts
export default defineNuxtConfig({
+   css: ['~/assets/css/main.css'],
    postcss: {
        plugins: {
        tailwindcss: {},
        autoprefixer: {},
        },
    },
})

ビルドプロセス

npm run dev

Tailwind CSS が使用できるか確認

pages ファイル作成

pages ディレクトリを作成してその中に index.vue を作成します。

index.vue
<template>
  <div>
    <h1>Index.vue</h1>
  </div>
</template>

app.vue 修正

pages ファイルを作成したので app.vue の内容も修正します。

app.vue
 <template>
   <div>
-    <NuxtWelcome />
+    <NuxtPage />
   </div>
 </template>

確認すると表示されていました。

ユーティリティクラスを付与してみる

確認用に適当なユーティリティクラスを付与してみます。

index.vue
<template>
  <div>
    <h1 class="text-3xl font-bold underline">Index.vue</h1>
  </div>
</template>

CSS で言うと、

font-size: 1.875rem;
line-height: 2.25rem;
font-weight: 700;
text-decoration-line: underline;

を追加しました。

確認してみると、

しっかり反映されていました。

Nuxt Color Mode セットアップ

Nuxt Color Mode は Color Mode を切り替えることができるモジュールです。

公式ドキュメント

インストール

npm install --save-dev @nuxtjs/color-mode

nuxt.config 追記

nuxt.config.ts
export default defineNuxtConfig({
    css: ['~/assets/css/main.css'],
    postcss: {
        plugins: {
        tailwindcss: {},
        autoprefixer: {},
        },
    },
+   modules: ['@nuxtjs/color-mode'],
})

Nuxt Color Mode の使い方

index.vue を修正しました

index.vue
<template>
  <div class="p-8">
    <h1 class="text-3xl font-bold underline">Index.vue</h1>
    <p>{{ $colorMode.preference }}</p>
    <div class="space-x-2">
      <button class="px-2 border border-1" @click="$colorMode.preference = 'dark'">dark</button>
      <button class="px-2 border border-1" @click="$colorMode.preference = 'light'">light</button>
    </div>
  </div>
</template>

$colorMode.preference は選択されたカラーモードが入っています。
更新する際も $colorMode.preference を更新します。

画面を確認すると、

ボタンをクリックすると $colorMode.preference の値が更新されているのがわかります。

また、Nuxt Color Mode は選択した Color Mode を <html> タグのクラスに付与してくれます。

<html> タグのクラスに dark-mode / light-mode が付与されています

Tailwind CSS のダークモードのクラスの使い方

Tailwind CSS にはダークモード用のクラスが用意されています。

https://tailwindcss.com/docs/dark-mode

通常のクラス名の前にdark:をつけるだけです。

クラス名を元にダークモードの切り替えを制御したいので tailwind.config に設定を追記します。

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
+ darkMode: 'class',
  content: [
      "./components/**/*.{js,vue,ts}",
      "./layouts/**/*.vue",
      "./pages/**/*.vue",
      "./plugins/**/*.{js,ts}",
      "./nuxt.config.{js,ts}",
      "./app.vue",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Tailwind CSS ではルートノードのクラス名がdarkの場合にdark:がついたスタイルを適応します。

なので、 <html> タグについたクラス dark-mode ではスタイルが適応されません。

この問題を解決するために、Nuxt Color Mode の設定を修正します。

nuxt.config.js
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  css: ['~/assets/css/main.css'],
  postcss: {
    plugins: {
      tailwindcss: {},
      autoprefixer: {},
    },
  },
  modules: ['@nuxtjs/color-mode'],
+ colorMode: {
+   classSuffix: '',
+ }
})

この設定を追記することで <html> タグに付与されるクラスを dark-mode から dark に変更できます。

ダークモードのスタイルが当たるか確認する。

index.vue
<template>
  <div class="p-8">
    <h1 class="text-3xl font-bold underline">Index.vue</h1>
    <p class="dark:bg-black dark:text-white">{{ $colorMode.preference }}</p> <!-- dark: クラスを付与 -->
    <div class="space-x-2">
      <button class="px-2 border border-1" @click="$colorMode.preference = 'dark'">dark</button>
      <button class="px-2 border border-1" @click="$colorMode.preference = 'light'">light</button>
    </div>
  </div>
</template>

$colorMode.preference が表示される <p> にdark:クラスを付与しました。

確認すると、dark: で付与したクラスが適応されているのがわかります。

これでdark:をつけることによってダークモード用のスタイルを当てられるようになりました!

※ダークモード例

最後に

ダークモードを実装する記事が意外と少なかったので記事にしました。
Nuxt Color Mode ではダークモード以外にもさまざまなカラーモードを実装できるので非常に使いやすかったです。

皆さんも良いカラーモードライフを!

Discussion