初めに
最近、Next.js
にTailwind CSS
で作成した個人ブログにダークモード機能を追加したので、その備忘録として。
Tailwindのダークモードを有効化する
TailwindのV-2からダークモードが組み込まれており、ダークモード時に指定の色に切り替えてくれるようになりました。
ダークモードを有効化するのは簡単で、tailwind.config.js
のdarkMode
にclass
かmedia
を指定するだけです。media
を指定した場合は、OSの設定に基づいて、自動でdarkモードに切り替えてくれますが、今回はユーザーがページ上でON/OFFの切り替えが出来るようにしたいので、class
を指定して、ダークモードを有効化させます。
詳細はTailwindのドキュメントに記載されてます。
module.exports = {
purge: [],
darkMode: 'class', //ダークモードを有効化する
theme: {
extend: {
colors: {
darkgrey: '#222831', //darkModeで使用したい色を拡張定義
},
},
},
variants: {
extend: {
},
},
plugins: [],
};
next-themesをインストールする
次にボタンを押下した際に、htmlタグのclassに対してdark
をアクティブ/非アクティブにするための実装が必要になります。
<html class="dark">
Tailwindのダークモードは、htmlタグのclassにdark
が付与されてる場合、以下のような記述で、ダークモード時の色を指定する事が出来ます。
<div className="dark:bg-darkgrey dark:text-white">
ドキュメントには現在のモードをlocalStorageに保存する方法が紹介されていますが、ここでは、next-themes
というライブラリを使って実装を進めます。
$ npm install next-themes
# or
$ yarn add next-themes
ライブラリをインストールしたら、_app.js
にThemeProvider
をimportします。
attributeにはclass
を指定しましょう。(※Tailwindのダークモードを使用するには、この記述が必要です)
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のいつもの書き方でダークモード時の色を指定してあげるだけです。
<div className="relative mb-10 dark:bg-darkgrey">
...
</div>
以上、これでお手軽にダークモードを実装することが出来ます。