You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We, as developers who blog, don't need JavaScript to support dark mode!
In fact, if you use JS to make dark mode work, it most likely won't work for users who have it disabled.
I will attempt to convince you that you don't need any JS and minimal CSS to get dark mode to work for your blog site. And I shall show you how to do it.
Use color-scheme meta tag or CSS property
color-scheme will get your site to look decent by making use of the browser's defaults for dark mode.
You can use either the meta tag1or the CSS property2, but prefer the meta tag. Reason stated below.
Meta tag
<!-- add this inside the <head> tag --><!-- the order in which you write defines the preferred color scheme if none specified by the OS setting --><metaname="color-scheme" content="dark light" />
One would prefer the use of this meta tag instead of CSS to prevent a flash of unstyled content (FOUC):
Honoring the color-scheme CSS property requires the CSS to be first downloaded (if it is referenced via <link rel="stylesheet">) and to be parsed. To aid user agents in rendering the page background with the desired color scheme immediately, a color-scheme value can also be provided in a [meta tag.]3
One significant advantage of using color-scheme is that you don't have to write any extra styles to make things readable. The user-agent (browser) stylesheet will take care of it. So you can support dark mode with little to no extra CSS.
Use the prefers-color-scheme media query to override user-agent styles
Now if you don't like the browser's default styles for dark mode, you can override them using the prefers-color-scheme media query4.
<metaname="color-scheme" content="dark light" />
<style>
@media (prefers-color-scheme: dark) {
body {
background-color: #111; /* Default on Chrome is black (#000) */
color: #eee; /* Default on Chrome is white (#fff) */
}
}
</style>
Having already set the color-scheme you will only need to worry about those elements whose user-agent stylesheet you don't particularly like.
For example, Chrome sets black as the background and white as the default text color, but designers don't recommend using pure black and white. GitHub's dark mode sets #c9d1d9 as the text color and #0d1117 as the background color in dark mode. These are easier on the eyes than browser defaults.
Use some JS if you really want (still an unsatisfactory solution)
Now, some of you might be itching to add some JS.
Well, in my opinion, you don't really need it, but one can argue that the user might find it time-consuming to go into their OS settings to change the appearance setting.
To solve that, you can give them a button to quickly change the dark mode setting directly on your site.
I would do the following.
Respect the user's OS setting using the color-scheme meta tag and prefers-color-scheme media query as mentioned above.
On top of that, allow them to override the above directly on the page. We can use a button to toggle dark mode using some JS.
<head><metaname="color-scheme" content="dark light" />
<style>
html {
color: darkslateblue;
background-color: oldlace;
}
@media (prefers-color-scheme: dark) {
html {
color: ivory;
background-color: darkslategray;
}
}
.dark {
color: ivory;
background-color: darkslategray;
}
.light {
color: darkslateblue;
background-color: oldlace;
}
</style></head><body><buttonid="toggle-dark">Toggle dark mode</button><!-- some content --><script>consttoggleDarkModeButton=document.getElementById("toggle-dark");toggleDarkModeButton.addEventListener("click",()=>{// Check if top level element has a dark classconstmanualDarkMode=Array.from(document.documentElement.classList).includes("dark");// Toggle dark modeif(manualDarkMode){document.documentElement.classList.remove("dark");document.documentElement.classList.add("light");}else{document.documentElement.classList.remove("light");document.documentElement.classList.add("dark");}});</script></body>
demo for manually overriding OS appearance setting with JS
But using JS still poses problems with elements you haven't explicitly overridden styles for, say, scrollbars on overflowing content. You may not even be able to solve that entirely because of the lack of CSS properties to style several elements (e.g. scrollbars)
Conclusion
In conclusion, it's best to use the color-scheme meta tag with prefers-color-scheme media query to support dark mode properly. Using JS is mostly going to worsen the user experience.
Support dark mode without JS (with CSS prefers-color-scheme media query)
Allow the user to change the theme for that session. We won't store their preference because the next time they visit the site, it might be at another time.
Seems like it would be challenging to achieve this with Tailwind CSS.
url: https://shreshth.dev/blog/dark-mode-that-just-works
slug: dark-mode
We, as developers who blog, don't need JavaScript to support dark mode!
In fact, if you use JS to make dark mode work, it most likely won't work for users who have it disabled.
I will attempt to convince you that you don't need any JS and minimal CSS to get dark mode to work for your blog site. And I shall show you how to do it.
Use
color-scheme
meta tag or CSS propertycolor-scheme
will get your site to look decent by making use of the browser's defaults for dark mode.You can use either the meta tag1 or the CSS property2, but prefer the meta tag. Reason stated below.
Meta tag
One would prefer the use of this meta tag instead of CSS to prevent a flash of unstyled content (FOUC):
Demo for using the
color-scheme
meta tagCSS property
Demo for using the
color-scheme
CSS propertycolor-scheme
is that you don't have to write any extra styles to make things readable. The user-agent (browser) stylesheet will take care of it. So you can support dark mode with little to no extra CSS.Use the
prefers-color-scheme
media query to override user-agent stylesNow if you don't like the browser's default styles for dark mode, you can override them using the
prefers-color-scheme
media query4.Having already set the
color-scheme
you will only need to worry about those elements whose user-agent stylesheet you don't particularly like.For example, Chrome sets black as the background and white as the default text color, but designers don't recommend using pure black and white. GitHub's dark mode sets
#c9d1d9
as the text color and#0d1117
as the background color in dark mode. These are easier on the eyes than browser defaults.Demo for using
color-scheme
meta tag withprefers-color-scheme
media queryUse some JS if you really want (still an unsatisfactory solution)
Now, some of you might be itching to add some JS.
Well, in my opinion, you don't really need it, but one can argue that the user might find it time-consuming to go into their OS settings to change the appearance setting.
To solve that, you can give them a button to quickly change the dark mode setting directly on your site.
I would do the following.
color-scheme
meta tag andprefers-color-scheme
media query as mentioned above.demo for manually overriding OS appearance setting with JS
But using JS still poses problems with elements you haven't explicitly overridden styles for, say, scrollbars on overflowing content. You may not even be able to solve that entirely because of the lack of CSS properties to style several elements (e.g. scrollbars)
Conclusion
In conclusion, it's best to use the
color-scheme
meta tag withprefers-color-scheme
media query to support dark mode properly. Using JS is mostly going to worsen the user experience.Demo for using
color-scheme
meta tag withprefers-color-scheme
media queryFootnotes
color-scheme
meta tag in html spec ↩color-scheme
CSS property on MDN ↩color-scheme
meta tag section from the web.dev article on Improved dark mode default styling ↩prefers-color-scheme
media query on MDN ↩The text was updated successfully, but these errors were encountered: