Support Ukraine

Dark Mode OpenStreetMap

Getting Google Maps to work in dark mode is a bit of a hassle, but you can do it by swapping map styles. OpenStreetMap doesn't have that functionality, since it serves pre-rendered tiles, but by taking inspiration from the Hue-Preserving Invert CSS Filter for Dark Mode, we can create a CSS filter that works reasonably well. The filter is almost the same, but with less saturated colors to give the dark mode map the same feel as the light mode one.

LightDark

The TLDR is that you put this somewhere in the HTML:

<svg style="position:fixed; left:0; top:0; width:0; height:0">
    <defs>
        <filter id="osm-tiles-darkmode" color-interpolation-filters="linearRGB">
            <feComponentTransfer>
                <feFuncR type="gamma" amplitude="1" exponent="0.700" offset="0.0"></feFuncR>
                <feFuncG type="gamma" amplitude="1" exponent="0.700" offset="0.0"></feFuncG>
                <feFuncB type="gamma" amplitude="1" exponent="0.700" offset="0.0"></feFuncB>
                <feFuncA type="gamma" amplitude="1" exponent="1" offset="0.0"></feFuncA>
            </feComponentTransfer>
            <feColorMatrix type="matrix" values="
                0.402 -1.174 -0.228 0.000 1.000 
                -0.598 -0.174 -0.228 0.000 1.000 
                -0.598 -1.174 0.772 0.000 1.000 
                0.000 0.000 0.000 1.000 0.000 
                "></feColorMatrix>
        </filter>
    </defs>
</svg>

Then it all works similar to Dark Mode Google Maps, but we leave out a lot and change the onColorSchemeChange function to add a filter to the tile pane:

var darkColorSchemeQuery = window.matchMedia('(prefers-color-scheme: dark)');

function onColorSchemeChange() {
    var tilePane = mapContainer.getElementsByClassName("leaflet-tile-pane")[0];
    if(this.colorSchemeQuery.matches){
        tilePane.style.filter = "url(#osm-tiles-darkmode)";
    } else {
        tilePane.style.filter = "unset";
    }
}

// Set up change event listener
darkColorSchemeQuery.addEventListener('change', function() { onColorSchemeChange(); });
// Initialize the map with the right colors
onColorSchemeChange();