Tailwind CSSのダークモードでページを再読込した際のチラつきを解消する
Tailwind CSSでダークモード対応をした際に、ダークモード状態でページを再読込みすると画面のチラつきが発生してしまった。
デフォルトのモードがlightモードになっており、useEffectでdark判定を行っているため、ページ読み込みから初回レンダリングが実行されるまでの間はlightモードが表示されてしまうのが原因。
気になるので何か手立てがないかと思って調べてみたところ、同様の現象に関するissueを発見。
issueに記載されていた、「use-dark-mode」のREADMEを参考に public/noflash.js
を追加し、ページ読み込み時にdark判定を行い、必要に応じてdark classを付与するように設定。
/* eslint-disable */
// Insert this script in your index.html right after the <body> tag.
// This will help to prevent a flash if dark mode is the default.
;(function () {
var storageKey = 'theme'
var classNameDark = 'dark'
function setClassOnDocumentBody() {
var html = document.getElementsByTagName('html')[0]
html.classList.add(classNameDark)
}
var preferDarkQuery = '(prefers-color-scheme: dark)'
var mql = window.matchMedia(preferDarkQuery)
var supportsColorSchemeQuery = mql.media === preferDarkQuery
var localStorageTheme = null
try {
localStorageTheme = localStorage.getItem(storageKey)
} catch (err) {}
var localStorageExists = localStorageTheme !== null
if (localStorageExists) {
if (localStorageTheme === classNameDark) {
setClassOnDocumentBody()
}
} else if (supportsColorSchemeQuery) {
setClassOnDocumentBody()
localStorage.setItem(storageKey, classNameDark)
}
})()
そして、bodyタグの直下に noflash.js
読み込みを追加する。
// pages/_document.tsx
import Document, { Html, Main, NextScript } from 'next/document'
import React from 'react'
export default class MyDocument extends Document {
render() {
return (
<Html>
<body className="dark:bg-gray-800 dark:text-gray-200">
<script src="/noflash.js" />
<Main />
<NextScript />
</body>
</Html>
)
}
}
これでダークモードで再読込しても画面のチラつきは発生しなくなった。