LoginSignup
13
10

More than 3 years have passed since last update.

Next.jsとtailwindを使ってダークモードをサクッと実装する

Posted at

初めに

最近、Next.jsTailwind CSSで作成した個人ブログにダークモード機能を追加したので、その備忘録として。

Tailwindのダークモードを有効化する

TailwindのV-2からダークモードが組み込まれており、ダークモード時に指定の色に切り替えてくれるようになりました。

ダークモードを有効化するのは簡単で、tailwind.config.jsdarkModeclassmediaを指定するだけです。mediaを指定した場合は、OSの設定に基づいて、自動でdarkモードに切り替えてくれますが、今回はユーザーがページ上でON/OFFの切り替えが出来るようにしたいので、classを指定して、ダークモードを有効化させます。

詳細はTailwindのドキュメントに記載されてます。

tailwind.config.js
module.exports = {
  purge: [],
  darkMode: 'class', //ダークモードを有効化する
  theme: {
    extend: {
      colors: {
        darkgrey: '#222831', //darkModeで使用したい色を拡張定義
      },
    },
  },
  variants: {
    extend: {
},
  },
  plugins: [],
};

next-themesをインストールする

次にボタンを押下した際に、htmlタグのclassに対してdarkをアクティブ/非アクティブにするための実装が必要になります。

htmlタグのclassにdarkを付与できるようにする必要がある
<html class="dark">

Tailwindのダークモードは、htmlタグのclassにdarkが付与されてる場合、以下のような記述で、ダークモード時の色を指定する事が出来ます。

dark
<div className="dark:bg-darkgrey dark:text-white">

ドキュメントには現在のモードをlocalStorageに保存する方法が紹介されていますが、ここでは、next-themesというライブラリを使って実装を進めます。

next-themes

next-themesをインストール
$ npm install next-themes
# or
$ yarn add next-themes

ライブラリをインストールしたら、_app.jsThemeProviderをimportします。
attributeにはclassを指定しましょう。(※Tailwindのダークモードを使用するには、この記述が必要です)

_app.tsx
import '../../styles/globals.css';
import '../../styles/common.css';
import { AppProps } from 'next/app';
import { ThemeProvider } from 'next-themes';

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ThemeProvider attribute="class">
      <Component {...pageProps} />
    </ThemeProvider>
  );
}

export default MyApp;

ダークモードを切り替えるボタンを作成する

切り替えるボタンは以下のようにしました。
useTheme()フックを利用して、テーマの切り替えを制御します。

import { useTheme } from 'next-themes';

const { theme, setTheme } = useTheme();

// レンダー後かを判定
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);

<button
  aria-label="DarkModeToggle"
  type="button"
  className="p-3 h-12 w-12 order-2 md:order-3 absolute left-2/4 transform -translate-x-2/4 md:relative md:left-0"
  onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
>
  {mounted && (
    <>
      {theme === 'dark' ? (
        <Moon height={'25'} width={'25'} />
      ) : (
        <Sun height={'25'} width={'25'} />
      )}
    </>
  )}
</button>

後は、Tailwindのいつもの書き方でダークモード時の色を指定してあげるだけです。

dark
<div className="relative mb-10 dark:bg-darkgrey">
...
</div>

以上、これでお手軽にダークモードを実装することが出来ます。

13
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10