Appearance
はじめに
TailwindCSS でダークモードを実装したところ、Chrome の Automatic dark mode で挙動確認した際に一部ダークモードが上手く切り替わらない問題に遭遇しました。
今回はその問題について解説します。
ダークモードの実装
TailwindCSS でダークモードを実装する方法は、公式ドキュメントに詳しく書かれています。
以下に手順を示します。
1. tailwind.config.ts の設定
今回は手動で切り替えを行えるように.dark を<body>
タグに付与することでダークモードを実装します。
tailwind.config.js
にダークモードの設定を追加します。(デフォルトは darkMode: "media" です)
js
// tailwind.config.js
module.exports = {
darkMode: "class",
theme: {
extend: {},
},
plugins: [],
};
2. CSS ファイルの編集
CSS ファイルにダークモードのスタイルを追加します。
*確認しやすいように設定色を変更しています。
css
/* global.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--color-text: blue;
--color-bg: red;
}
.dark {
--color-text: red;
--color-bg: blue;
}
body {
color: var(--color-text);
background-color: var(--color-bg);
}
3. ダークモードの切り替え
ダークモードの切り替えを行うためのボタンを用意します。
tsx
import { useEffect, useState } from "react";
const ToggleDarkMode = () => {
const prefersColorSchema = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
const [isDarkMode, setIsDarkMode] = useState(prefersColorSchema);
const handleDarkMode = () => {
if (isDarkMode) {
document.body.classList.add("dark");
} else {
document.body.classList.remove("dark");
}
setIsDarkMode(!isDarkMode);
};
useEffect(() => {
if (isDarkMode) {
document.body.classList.add("dark");
} else {
document.body.classList.remove("dark");
}
}, [isDarkMode]);
return (
<button
type="button"
aria-label="toggle dark mode"
className="mx-2 flex items-center justify-center"
onClick={handleDarkMode}
>
{isDarkMode ? "light mode" : "dark mode"}
</button>
);
};
export default ToggleDarkMode;
ダークモードを確認すると、手動で切り替えることができていると思います。
Automatic dark mode でハマった問題
Chrome の Automatic dark mode は、OS のダークモード設定に合わせて自動でダークモードを切り替えてくれる機能です。
この機能を使うと、ユーザーが好みのモードで閲覧できるようになります。
しかし、この機能を使うとダークモードの切り替えで問題が発生する可能性があります。
問題
今回はまった問題は Automatic dark mode でダークモードに設定後、ライトモードに切り替えた際に一部のスタイルがダークモードのままになる問題でした。
具体的には、背景色や文字色が var()で指定している色ではなく、デフォルトのダークモードの色になってしまうという問題です。
解決策
この問題は、color-scheme を指定してあげることで解決できました。
css
/* global.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
color-scheme: light dark;
--color-text: blue;
--color-bg: red;
}
.dark {
--color-text: red;
--color-bg: blue;
}