WEB

【CSS】color-mix() と light-dark() でライトテーマ・ダークモード対応

CSSの新機能 light-dark() 関数と color-mix() 関数を使って、JavaScriptやSassを使わずに、CSSだけでライトモード・ダークモードを実装してみました

light-dark()関数とは

light-dark() 関数は、ユーザーの環境の設定がライトモードかダークモードかに応じて、自動的に色を切り替える関数です。
light-dark() 関数を有効にするには、:rootcolor-scheme: light dark;を設定します。colorbackground-colorに2つの色を指定することができます。

:root {
  color-scheme: light dark;
}
body {
  color: light-dark(#333b3c, #efefec);
  background-color: light-dark(#efedea, #223a2c);
}

 

color-mix()関数とは

color-mix() 関数は、2025年4月に主要なブラウザで使えるようになった新機能で、2つの色を指定された割合で混ぜあわせることができるCSS関数です。カラーパレットを作成する時に重宝しそうです。

例えば、赤、黄色系のカラーパレットを作成したい時
(色味はtailwindcssを一部参考にさせていただきました)

完成イメージ

HTML

<h2><span>●</span> 赤</h2>
<div class="palette">
  <div class="red-100">red-100</div>
  <div class="red-200">red-200</div>
  <div class="red-300">red-300</div>
  <div class="red-400">red-400</div>
  <div class="red-500">red-500</div>
  <div class="red-600">red-600</div>
  <div class="red-700">red-700</div>
</div>

<h2><span>●</span> 黄色</h2>
<div class="palette">
  <div class="yellow-100">yellow-100</div>
  <div class="yellow-200">yellow-200</div>
  <div class="yellow-300">yellow-300</div>
  <div class="yellow-400">yellow-400</div>
  <div class="yellow-500">yellow-500</div>
  <div class="yellow-600">yellow-600</div>
  <div class="yellow-700">yellow-700</div>
</div>

 

CSS
ベースの色に黒、または白を調合し、割合を変更するだけで自動で色を作成してくれます。

:root {
  --white: #ffffff;
  --black: #000000;
  --base-red: #ef4444;
  --base-yellow: #facc15;

  /* 赤系パレット */
  --red-100: color-mix(in oklab, var(--white) 85%, var(--base-red) 15%);
  --red-200: color-mix(in oklab, var(--white) 70%, var(--base-red) 30%);
  --red-300: color-mix(in oklab, var(--white) 50%, var(--base-red) 50%);
  --red-400: color-mix(in oklab, var(--white) 30%, var(--base-red) 70%);
  --red-500: var(--base-red);
  --red-600: color-mix(in oklab, var(--black) 20%, var(--base-red) 80%);
  --red-700: color-mix(in oklab, var(--black) 40%, var(--base-red) 60%);

  /* 黄色系パレット */
  --yellow-100: color-mix(in oklab, var(--white) 85%, var(--base-yellow) 15%);
  --yellow-200: color-mix(in oklab, var(--white) 70%, var(--base-yellow) 30%);
  --yellow-300: color-mix(in oklab, var(--white) 50%, var(--base-yellow) 50%);
  --yellow-400: color-mix(in oklab, var(--white) 30%, var(--base-yellow) 70%);
  --yellow-500: var(--base-yellow);
  --yellow-600: color-mix(in oklab, var(--black) 20%, var(--base-yellow) 80%);
  --yellow-700: color-mix(in oklab, var(--black) 40%, var(--base-yellow) 60%);
}

/* 赤パレット */
.red-100 {
  background-color: var(--red-100);
}
.red-200 {
  background-color: var(--red-200);
}
.red-300 {
  background-color: var(--red-300);
}
.red-400 {
  background-color: var(--red-400);
}
.red-500 {
  background-color: var(--red-500);
  color: var(--white)
}
.red-600 {
  background-color: var(--red-600);
  color: var(--white)
}
.red-700 {
  background-color: var(--red-700);
  color: var(--white)
}

/* 黄色パレット */
.yellow-100 {
  background-color: var(--yellow-100);
}
.yellow-200 {
  background-color: var(--yellow-200);
}
.yellow-300 {
  background-color: var(--yellow-300);
}
.yellow-400 {
  background-color: var(--yellow-400);
}
.yellow-500 {
  background-color: var(--yellow-500);
}
.yellow-600 {
  background-color: var(--yellow-600);
}
.yellow-700 {
  background-color: var(--yellow-700);
  color: var(--black)
}

 

実装方法

イメージ
簡単なダッシュボードを作成しました。

HTML

  <!-- サイドナビ -->
  <nav>
    <a href="#" class="nav-item"><span class="material-icons">home</span> ホーム</a>
    <a href="#" class="nav-item"><span class="material-icons">palette</span> デザイン</a>
    <a href="#" class="nav-item"><span class="material-icons">settings</span> 設定</a>
  </nav>

  <!-- メインコンテンツ -->
  <main>
    <div class="top-bar">
      <span class="material-icons">search</span>
      <span class="material-icons">notifications</span>
      <span class="material-icons">account_circle</span>
    </div>

    <div class="info card">
      <h2>お知らせ</h2>
      <p>次回のメンテナンスは5月1日です。</p>
      <a href="#" class="button">スケジュール確認</a>
    </div>

  </main>

 

CSS
※装飾のスタイルは省略しています

STEP1:基本設定

:rootcolor-scheme: light dark;を記述し、カラースキームを宣言。
ベースとなる色をライト時とダーク時2色を設定。

:root {
  color-scheme: light dark;

  --primary: #6750A4;
  --white: #ffffff;
  --black: #2a2a2a;

  --surface: light-dark(color-mix(in oklab, var(--primary) 5%, var(--white)),
      color-mix(in oklab, var(--primary) 5%, var(--black)));
  --surface-variant: light-dark(color-mix(in oklab, var(--primary) 15%, var(--white)),
      color-mix(in oklab, var(--primary) 15%, var(--black)));

  --surface-text: light-dark(#2a2a2a, #ffffff);
  --primary-text: light-dark(#ffffff, #ffffff);
}

 

STEP2:css変数を使用し、各項目の背景やフォントに色を指定する

body {
  background-color: var(--surface);
  color: var(--surface-text);
}

/* Sidebar */
nav {
  background-color: var(--surface-variant);
}

.nav-link {
  color: var(--surface-text);
}

.nav-link:hover {
  background-color: color-mix(in oklab, var(--surface-variant) 70%, var(--primary));
  color: var(--primary-text);
}

/* Main content */

.toolbar {
  color: var(--surface-text);
}

.section {
  background-color: var(--surface-variant);
}

.btn {
  background-color: var(--primary);
  color: var(--primary-text);
}

.btn:hover {
  background-color: color-mix(in oklab, var(--primary) 85%, var(--white));
}

 

css変数を活用してみようはじめに ウェブサイトで複数のフォントウェイトが指定されている場合、「Mediumは500?SemiBoldは600だっけ??」と数値...

 

まとめ

color-mix()light-dark() を組み合わせることで、CSSだけで配色の自動調整とテーマ対応が可能になります。色の配色が苦手な私にとって、デザインの一貫性を保てるのでとてもありがたい機能です!今後のCSS設計にぜひ取り入れたいと思います。

対応ブラウザ

2025年4月現在、主要なブラウザに対応しています。

 

参考サイト

こちらのサイトを参考にさせていただきました。

 
 
 

 

N.T
平日はコーディング、週末は子供と公園を走り回っています。