Google Maps[a] doesn't support the prefers-color-scheme: dark
media query, and therefore remain bright even when the rest of the website has gone dark. But you can get something close to a dark mode Google Maps with a little bit of JavaScript.
1. The Map
1.1. The Color Scheme
Start by grabbing the Styled Maps - Night Mode[b] list of map stylers from Google's documentation, and create a default empty list of stylers for the light mode.
var LIGHT_MODE_STYLES = [];
var DARK_MODE_STYLES = [
{ elementType: "geometry", stylers: [{ color: "#242f3e" }] },
{ elementType: "labels.text.stroke", stylers: [{ color: "#242f3e" }] },
{ elementType: "labels.text.fill", stylers: [{ color: "#746855" }] },
...
1.2. Setting the Color Scheme
This is how you set a style on a map - simply call the setOptions
method on the map. This will not change any other map options.
map.setOptions({
styles: DARK_MODE_STYLES
})
1.3. Switching Color Scheme
Next step is to switch the map style when the color scheme changes (and initialize the map with the right style):
var darkColorSchemeQuery = window.matchMedia('(prefers-color-scheme: dark)');
function onColorSchemeChange() {
if(darkColorSchemeQuery.matches){
map.setOptions({
styles: DARK_MODE_STYLES
});
} else {
map.setOptions({
styles: LIGHT_MODE_STYLES
});
}
}
// Set up change event listener
darkColorSchemeQuery.addEventListener('change', function() { onColorSchemeChange(); });
// Initialize the map with the right colors
onColorSchemeChange();
1.4. Map Controls
You can replace the map controls with your own (and I suspect that sufficiently hackish CSS rules can restyle the existing controls), but I really don't want to spend time keeping up with Google. Especially getting the little droppable Street View Pegman[c] right seems like a nightmare. I just skipped this.
2. Info Windows
If you use Maps's own InfoWindow
, you'll notice it's not very stylable.
2.1. InfoBubble
InfoBubble[d], which is stylable and available on GitHub, solves that problem. But you need to use CSS Variables to make it switch along with the user's preference:
html {
--text-background: #fff;
--panel-border: #b8b8b8;
}
@media screen and (prefers-color-scheme: dark) {
html {
--text-background: #000;
--panel-border: #383838;
}
}
Then provide the variables to InfoBubble
as style property values:
var infoBubbleOptions = {
backgroundColor: "var(--text-background)",
borderColor: "var(--panel-border)"
};
2.2. Scrollbars
To get the scrollbars in the info bubble to support dark mode, add a conditional color-scheme
property on the :root
element.
@media screen and (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
}
}