I read a recent blog post by Jim Nelson about “flash of inaccurate color theme” and I’ve been noticing it more and more.

There are plenty of sites that get dark mode / theming right: Stack Overflow, GitHub, Google, etc. but it isn’t universal.

And here are some examples:

Twitch’s mobile site

The Twitch desktop site is fine, but there is an initial flash of the wrong theme with the mobile site.

On a repeat visit, the issue doesn’t persist because a cookie is set for the theme and the second page visit includes the proper styling.

Youtube’s mobile site

Like Twitch, the desktop site is fine. On mobile however, there is a flash of the wrong theme.

The issue in this case is that the site loads with the background set to a light color via inlined css. Then a CSS file that defines the theme background color loads and overrides the initial color with the correct theme.

Sentry

Sentry shows an initial static page while the JS of the app loads in, this static page doesn’t have theming, so it results in a mismatch when the dashboard loads.

Stripe API docs

The Stripe API docs don’t have the proper theme on initial load. Future loads result in the correct theme due to a cookie being set.

Feedly

Pretty much the same setup as Sentry, there is an initial static page that is shown while the JS loads, and it doesn’t have proper theming. Their mobile app has a similar issue.

Apollo GraphQL docs

The Apollo docs look pretty buggy! The server returns html with a dark mode css class name set, then on load the class name switches to light, before quickly switching back to dark. I think the issue is that there is a transition-property: background-color on the <body>, so the switch is delayed by transition-duration: var(--chakra-transition-duration-normal); which is set to 200ms.

Conclusion

Initial load is important, be careful when implementing theming.