Dark Mode Google Maps
 
Support Ukraine

Dark Mode Google Maps

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;
    }
}