Avoiding Flash of Inaccurate Theme Color [Edit: I Was Wrong]
Update 2021-06-02: I fired off this post too quickly. I got some good feedback on Twitter, including a note from @zcorpan about a detail I missed: I had a transition
property on the body
! When I moved the background-color
from body
to html
, the flash disappeared because the transition wasn’t taking effect.
Upon further investigation, I realized that it doesn’t matter if the background color is on the body or the root — as long as you don’t have a transition
on either. But if you do have a transition
, there’s some interesting behavior on how the document transitions based on whether you have the color-scheme
property set. So I learned that — plus to consider a self-imposed delay when firing off posts late at night.
[Firing off a quick post here about a rather simple problem I suppose I should’ve known the answer to, but didn’t. So I’m documenting it in case, someday, somebody else has the same question.]
Are you running into a nasty case of flash of inAccurate coloR Theme (FART)?
I’d been noticing it on my icon gallery sites but not any of my other sites so I was wondering what was wrong.
I figured it had to be a difference in implementation, as my icon gallery sites were the first sites I implemented dark mode on, so like many things, I probably did it wrong the first time and never went back and fixed it.
Here’s what I was seeing: when in dark mode, I’d see the page flash from light to dark as I transitioned between page requests.
There’s no synchronous JavaScript at play here applying dark mode classes or the like. It’s only @media (prefers-color-scheme)
. So why is it flashing like this?
My first thought was, “I don’t think I knew about color-scheme when I did dark mode here, maybe that’s why?” So I added color-scheme: light dark
to my CSS. It didn’t fix my issue, but it did do something: it changed from a light to dark flash between page requests, to a dark to slightly lighter dark flash between page requests.
Interesting—but I’m still seeing the flash, so problem not solved.
As I looked at my CSS trying to think what the problem might be, I realized my page background color was being applied to the <body>
element and not the root or <html>
element. My first thought was, “Well I should stick it on the root, that just seems proper.” But as I was changing it, I remembered Chris’ CSS-Tricks post from way back and my brain thought, “I wonder if this is actually the fix?”
Sure enough, that fixed the problem!
So: if you’re seeing a flash of color as you transition between pages in dark mode (and you’re not doing anything sophisticated like applying dark mode classes via JavaScript) chances are you might just be applying your page’s background color to the wrong element! Put it on :root
or html
element, not on the body
!