Whilst tweaking my website at the beginning of the year I was surprised how easy it is to support Light Mode or Dark Mode themes. The implementation below isn't a user toggle Javascript thing, browsers now have a "media preference", that is if your iPhone, Mac or Windows 10 is setup for Light Mode then it'll prefer a lighter style and the opposite is true, if you're setup for Dark Mode then a darker style is displayed.
Example 1: Light/White Website with optional Dark Mode.
To start with, let's take the initial template from bootstrap and add 8 lines of code (mostly whitespace!) to include an optional inverted view; this is what we add...
<style type="text/css">
@media (prefers-color-scheme: dark) {
body {
background-color: black;
color: white;
}
}
</style>
So the final page looks like this, save it as light_eg.html
on your desktop.
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<title>Hello, world!</title>
<style type="text/css">
@media (prefers-color-scheme: dark) {
body {
background-color: black;
color: white;
}
}
</style>
</head>
<body>
<h1>Hello, world!</h1>
<p>Example HTML from <a href="https://getbootstrap.com/docs/4.4/getting-started/introduction/">bootstrap</a>
</body>
</html>
By default the page will be the normal bootstrap colours, dark text on a white background but if the user has setup their device in Dark Mode the site will be white text on a black background.
Example 2: Dark/Black Website with optional Light Mode.
Ok, so what if your use case was the same as mine; your site is normally dark but you want to provide a brighter version for people who prefer the lighter side of the net.
This time, lets start with the full HTML example: dark_eg.html
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootswatch CSS -->
<link href="https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/cyborg/bootstrap.min.css" rel="stylesheet" integrity="sha384-l7xaoY0cJM4h9xh1RfazbgJVUZvdtyLWPueWNtLAphf/UbBgOVzqbOTogxPwYLHM" crossorigin="anonymous">
<title>Hello, world!</title>
<style type="text/css">
@media (prefers-color-scheme: light) {
body, h1, h2, h3 {
background-color: white;
color: black;
}
}
</style>
</head>
<body>
<h1>Hello, world!</h1>
<p>Example HTML from <a href="https://getbootstrap.com/docs/4.4/getting-started/introduction/">bootstrap</a> with dark <a href="https://bootswatch.com/cyborg/">Cyborg Theme</a>
</body>
</html>
In this example we're using a dark bootstrap theme called cyborg, again we add in our 8 lines, but notice something a little different:
<style type="text/css">
@media (prefers-color-scheme: light) {
body, h1, h2, h3 {
background-color: white;
color: black;
}
}
</style>
In the dark example, additional changes are needed for h1
, h2
& h3
so this is the gotcha to look out for when using off-the-shelf themes. In the cyborg theme, the headings do not inherited their colour from body, they are hard set; when the colour scheme is inverted the white on white text disappears. To fix the issue some additional h1
, h2
& h3
colours are needed, so make sure you test your site in each mode to capture any missing options.
Footnotes
- This feature isn't dependent on bootstrap, it simply makes a good example as it's a style/css framework that's very common.
- User's cannot choose a theme, this approach simply honours their system wide preference
- Inspired by Flavio's dark mode post: https://flaviocopes.com/dark-mode/