この記事の概要
Tailwind CSSの公式ドキュメントにはダークモードの実現の仕方が記載されています。
ドキュメント内にあるサンプルコードはこのようになっています。
<div class="bg-white dark:bg-slate-800 rounded-lg px-6 py-8 ring-1 ring-slate-900/5 shadow-xl">
<h3 class="text-slate-900 dark:text-white mt-5 text-base font-medium tracking-tight">Writes Upside-Down</h3>
<p class="text-slate-500 dark:text-slate-400 mt-2 text-sm">
The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.
</p>
</div>
ダークモード時に色が変わる要素にdark:
をつけて色を指定しているのですが、正直面倒ではありませんか?
というわけでdark:
をつけずにダークモードを実現できるやり方を記事にしました。
この記事を投稿した2024年12月現在、Tailwind CSSはv4がベータバージョンとして提供されています。
stableなのはv3ですが、もう間も無くv4へ移行すると考え、v3とv4両方でのやり方を紹介します。
完成物のイメージ
次のようなコードを書くと
<div className="flex flex-col gap-6 text-4xl bg-background p-8">
<div className="bg-surface rounded p-6">
<p className="text-text">Default color text</p>
</div>
<div className="bg-surface rounded p-6">
<p className="text-primary">Primary color text</p>
</div>
</div>
次のような分岐を実現できます。
ライトモード | ダークモード |
---|---|
dark:
をつける必要はなくsurface
やtext
など自分で作成したエイリアスを指定するだけで済みます。
v3でのやり方
基準となるCSSファイル(index.css
, main.css
, out.css
などに該当する)ものにCSSカスタムプロパティを定義します。
グローバルトークンを定義した上で、ライトモード用とダークモード用、それぞれのエイリアストークンを定義します。
@tailwind base;
@tailwind components;
@tailwind utilities;
+ @layer base {
+ :root {
+ /* グローバルトークン */
+ --color-gray-0: 255 255 255;
+ --color-gray-10: 245 245 245;
+ /* 以降、必要なものを定義 */
+
+ /* ライトモードでのエイリアストークン */
+ --color-background: var(--color-gray-10);
+ --color-surface: var(--color-gray-0);
+ --color-text: var(--color-gray-100);
+ --color-primary: var(--color-red-60);
+ /* 以降、必要なものを定義 */
+ }
+
+ @media (prefers-color-scheme: dark) {
+ :root {
+ /* ダークモードでのエイリアストークン */
+ --color-background: var(--color-gray-100);
+ --color-surface: var(--color-gray-90);
+ --color-text: var(--color-gray-0);
+ --color-primary: var(--color-red-50);
+ /* 以降、必要なものを定義 */
+ }
+ }
+ }
次にtailwind.config.js
でcolors
を定義します。
先ほど定義したエイリアストークンを指定します。
/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html", "./src/**/*.tsx"],
theme: {
+ colors: {
+ background: "rgb(var(--color-background))",
+ surface: "rgb(var(--color-surface))",
+ text: "rgb(var(--color-text))",
+ primary: "rgb(var(--color-primary))",
+ // 以降、必要なものを定義
+ },
},
plugins: [],
};
これで完成物のイメージ
に載せたものが実現できます。
v4でのやり方
若干ハック気味の方法です。もしかしたらより良い方法があるかもしれません。あるいは今後のアップデートで素直な実装が可能になるかもしれません。
- カスタムプロパティを宣言するのが
@leayer base
の中ではなく@theme
の中に変更-
@theme
の中では:root
は不要
-
- 色指定において
rgb
やhsl
などが必要になった- v3ではつけると上手く動いてくれない
ただし@theme
の中にはカスタムプロパティか@keyframes
しか入れられないため、同名のレイヤーにダークモード時の値を入れています。
推奨されたやり方ではなく、今後どうなるか分からないため、お気をつけください。
- @tailwind base;
- @tailwind components;
- @tailwind utilities;
+ @import "tailwindcss";
- @layer base {
- :root {
- --color-gray-0: 255 255 255;
- --color-gray-10: 245 245 245;
- --color-gray-90: 45 45 45;
- --color-gray-100: 30 30 30;
- --color-red-50: 255 105 105;
- --color-red-60: 233 0 0;
- --color-background: var(--color-gray-10);
- --color-surface: var(--color-gray-0);
- --color-text: var(--color-gray-100);
- --color-primary: var(--color-red-60);
- }
- }
+ @theme {
+ --color-gray-0: rgb(255 255 255);
+ --color-gray-10: rgb(245 245 245);
+ --color-gray-90: rgb(45 45 45);
+ --color-gray-100: rgb(30 30 30);
+ --color-red-50: rgb(255 105 105);
+ --color-red-60: rgb(233 0 0);
+ --color-background: var(--color-gray-10);
+ --color-surface: var(--color-gray-0);
+ --color-text: var(--color-gray-100);
+ --color-primary: var(--color-red-60);
+ }
+ @layer theme {
@media (prefers-color-scheme: dark) {
:root {
--color-background: var(--color-gray-100);
--color-surface: var(--color-gray-90);
--color-text: var(--color-gray-0);
--color-primary: var(--color-red-50);
}
}
+ }