Tailwind CSSでダークモード

commits3 min read読了の目安(約3500字 2

昨今のアプリケーションでは、ダークモードを提供しているのがもはや当たり前になってきました。
OSのレベルでダークモードを設定することができ、ダークモードが提供されていないサイトは眩しく感じしてしまって敬遠してしまうなんて経験はあるのではないでしょうか?

そんな一般化されたダークモードの提供をTailwind CSSで実装します。

tailwind.config.jsの設定の変更

Tailwind CSSでダークモードを有効化するためには、tailwind.config.jsファイルを修正します。
darkModeの値にmediaまたはclassを設定します。

module.exports = {
  purge: ['./public/**/*.html'],
  theme: {
    extend: {},
  },
  variants: {},
  plugins: [],
  darkMode: // 'media' or 'class'
}

media

mediaを指定した場合には、OSの設定に基づいてダークモードを適用するかどうか決定します。

module.exports = {
  darkMode: 'media',
  // ...
}

OSのダークモードの設定値はprefers-color-schemeによって取得されます。

mediaを指定した場合には、手動でダークモードとライトモードを切り替えることができません。
そのため、次に説明するclassを指定することが一般的でしょう。

class

ユーザーによって手動でダークモードに切り替えられるようにするためには、classを指定します。

module.exports = {
  darkMode: 'class',
  // ...
}

classが指定された場合には、自身の祖先要素に対してdarkというクラスが付与されている場合に限り、ダークモードが適用されます。
実際には、<html>タグに対してdarkクラスを付与することになるでしょう。

<html class="dark">
  <body>
     <!-- ... -->
  </body>
</html>

公式サイトにJavaScriptによってダークモードを切り替える方法が記載されているので抜粋します。

// On page load or when changing themes, best to add inline in `head` to avoid FOUC
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
  document.documentElement.classList.add('dark')
} else {
  document.documentElement.classList.remove('dark')
}

// Whenever the user explicitly chooses light mode
localStorage.theme = 'light'

// Whenever the user explicitly chooses dark mode
localStorage.theme = 'dark'

// Whenever the user explicitly chooses to respect the OS preference
localStorage.removeItem('theme')

https://tailwindcss.com/docs/dark-mode#toggling-dark-mode-manually

はじめに、ローカルストレージのthemeの値を確認します。
その値がdarkであった場合には、<html>タグにdarkクラスを付与します。

ローカルストレージに値が存在しない場合には、window.matchMedia('(prefers-color-scheme: dark)').matchesによってOSのダークモードの設定を確認します。

window.matchMediaは、指定されたメディアクエリのパースされた値を返します。
window.matchMedia('(prefers-color-scheme: dark)').matchesは、OSの設定がダークモードのときにはtrueを返します。

ボタンクリックなどによってダークモードを切り替える場合には、次のような例で良いでしょう。

<button onclick="toggleDarkMode()">テーマ切り替え</button>

<script>
  function toggleDarkMode() {
    // htmlタグにdarkクラスが含まれているかどうか
    if (document.documentElement.contains('dark') {
        // darkクラスが含まれているならライトモードに変更
        document.documentElement.remove('dark')
        localStorage.theme = 'light'
    } else {
        // darkクラスが含まれていないならダークモードに変更
      document.documentElement.add('dark')
      localStorage.theme = 'dark'
    }
  }
</script>

ダークモード時のスタイルの指定

ダークモード時に適用されるスタイルの指定の仕方を見ていきましょう。
至って単純で、ダークモード適用時に上書きしたいスタイルに対してdark:のプレフィックスを指定するだけです。

<body class="min-h-screen bg-gray-100 dark:bg-gray-800 dark:text-gray-50">
  <h1 class="text-2xl">Hello World!</h1>
</body>

それぞれ次のようにスタイルが適用されます。

  • ライトモード

light-theme

  • ダークモード

dark-theme

終わりに

以上のように、Tailwind CSSでは簡単にダークモードを提供できます。
また、ユーティリティクラスの使いやすさはそのままダークモードのスタイルの指定にも適用できるので、細かい調整もしやすく嬉しい限りです。