Static Maps At Night
Tags: googlemaps, googlecloud, maps, darkmode
Published: 2021-04-16 02:22:12

Google's [Static Maps API](https://developers.google.com/maps/documentation/maps-static/overview) renders a map that looks great against a white background and other light websites but stands out like a bright TV in a dark room when your users switch over to dark / night mode - ouch!

Traditional techniques for making images dark mode friendly involve using [CSS filters](https://css-tricks.com/a-complete-guide-to-dark-mode-on-the-web/#dark-mode-images) to reduce the brightness and up the contrast which dulls the color a bunch but doesn't give us a completely dark map like you may see on your phone:
![Static Map w/ CSS filters](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ei3y5phy5q5r0m9zlx4r.jpg)

We can do something more clever using some basic HTML tags and the Static Map API's styling features.

Given an image tag like:

`<img src="https://maps.googleapis.com/maps/api/staticmap?...">`

We can wrap it in a `<picture>` element that is smart enough to swap to a styled static map when the browser is requesting dark mode. To get that dark mode styling, we can add `style` tags to change all the light map features to night-friendly colors.

```html
<picture>
  <source
    media="(prefers-color-scheme: dark)"
    srcset="https://maps.googleapis.com/maps/api/staticmap?<YOUR_MAP_PARAMS>&style=element%3Ageometry%7Ccolor%3A0x242f3e&style=element%3Alabels.text.stroke%7Ccolor%3A0x242f3e&style=element%3Alabels.text.fill%7Ccolor%3A0x746855&style=feature%3Aadministrative.locality%7Celement%3Alabels.text.fill%7Ccolor%3A0xd59563&style=feature%3Apoi%7Celement%3Alabels.text.fill%7Ccolor%3A0xd59563&style=feature%3Apoi.park%7Celement%3Ageometry%7Ccolor%3A0x263c3f&style=feature%3Apoi.park%7Celement%3Alabels.text.fill%7Ccolor%3A0x6b9a76&style=feature%3Aroad%7Celement%3Ageometry%7Ccolor%3A0x38414e&style=feature%3Aroad%7Celement%3Ageometry.stroke%7Ccolor%3A0x212a37&style=feature%3Aroad%7Celement%3Alabels.text.fill%7Ccolor%3A0x9ca5b3&style=feature%3Aroad.highway%7Celement%3Ageometry%7Ccolor%3A0x746855&style=feature%3Aroad.highway%7Celement%3Ageometry.stroke%7Ccolor%3A0x1f2835&style=feature%3Aroad.highway%7Celement%3Alabels.text.fill%7Ccolor%3A0xf3d19c&style=feature%3Atransit%7Celement%3Ageometry%7Ccolor%3A0x2f3948&style=feature%3Atransit.station%7Celement%3Alabels.text.fill%7Ccolor%3A0xd59563&style=feature%3Awater%7Celement%3Ageometry%7Ccolor%3A0x17263c&style=feature%3Awater%7Celement%3Alabels.text.fill%7Ccolor%3A0x515c6d&style=feature%3Awater%7Celement%3Alabels.text.stroke%7Ccolor%3A0x17263c">
  <img src="https://maps.googleapis.com/maps/api/staticmap?<YOUR_MAP_PARAMS>">
</picture
```

The important part of that `<source>` tag is the **`media="(prefers-color-scheme: dark)"`** to indicate it should be shown during dark times and appending all the **style** tags (below) which encode dark-friendly map styles.

`&style=element%3Ageometry%7Ccolor%3A0x242f3e&style=element%3Alabels.text.stroke%7Ccolor%3A0x242f3e&style=element%3Alabels.text.fill%7Ccolor%3A0x746855&style=feature%3Aadministrative.locality%7Celement%3Alabels.text.fill%7Ccolor%3A0xd59563&style=feature%3Apoi%7Celement%3Alabels.text.fill%7Ccolor%3A0xd59563&style=feature%3Apoi.park%7Celement%3Ageometry%7Ccolor%3A0x263c3f&style=feature%3Apoi.park%7Celement%3Alabels.text.fill%7Ccolor%3A0x6b9a76&style=feature%3Aroad%7Celement%3Ageometry%7Ccolor%3A0x38414e&style=feature%3Aroad%7Celement%3Ageometry.stroke%7Ccolor%3A0x212a37&style=feature%3Aroad%7Celement%3Alabels.text.fill%7Ccolor%3A0x9ca5b3&style=feature%3Aroad.highway%7Celement%3Ageometry%7Ccolor%3A0x746855&style=feature%3Aroad.highway%7Celement%3Ageometry.stroke%7Ccolor%3A0x1f2835&style=feature%3Aroad.highway%7Celement%3Alabels.text.fill%7Ccolor%3A0xf3d19c&style=feature%3Atransit%7Celement%3Ageometry%7Ccolor%3A0x2f3948&style=feature%3Atransit.station%7Celement%3Alabels.text.fill%7Ccolor%3A0xd59563&style=feature%3Awater%7Celement%3Ageometry%7Ccolor%3A0x17263c&style=feature%3Awater%7Celement%3Alabels.text.fill%7Ccolor%3A0x515c6d&style=feature%3Awater%7Celement%3Alabels.text.stroke%7Ccolor%3A0x17263`

![Map showing dark mode style](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rp1r1kcmh45hdc7cnppl.png)

Presto! When users visit their site in a browser supporting night mode, the media query will kick in and render the styled map. Users browsing in light mode (or without support for night mode) will see the regular style. The `<picture>` element is smart enough to only load 1 image, so you shouldn't be charged twice.

**WARNING:** If you're using URL Signing to better secure your Static Maps requests, you will need to generate a new signature for the styled map!

Here's a JSFiddle that shows it all in action, you'll see a light or dark map depending on what your browser is currently requesting.

{% jsfiddle https://jsfiddle.net/bamnet/4hfw35v2/ html,result %}