2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CSSAdvent Calendar 2024

Day 13

Tailwind CSSでdark:を使わずにダークモードを実現する

Last updated at Posted at 2024-12-12

この記事の概要

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:をつける必要はなくsurfacetextなど自分で作成したエイリアスを指定するだけで済みます。

v3でのやり方

基準となるCSSファイル(index.css, main.css, out.cssなどに該当する)ものにCSSカスタムプロパティを定義します。

グローバルトークンを定義した上で、ライトモード用とダークモード用、それぞれのエイリアストークンを定義します。

index.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.jscolorsを定義します。
先ほど定義したエイリアストークンを指定します。

tailwind.config.js
  /** @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は不要
  • 色指定においてrgbhslなどが必要になった
    • v3ではつけると上手く動いてくれない

ただし@themeの中にはカスタムプロパティか@keyframesしか入れられないため、同名のレイヤーにダークモード時の値を入れています。
推奨されたやり方ではなく、今後どうなるか分からないため、お気をつけください。

index.css
- @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);
      }
    }
+ }
2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?