Skip to content

Instantly share code, notes, and snippets.

@BrendonKoz
Last active March 19, 2024 08:29
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save BrendonKoz/b1df234fe3ee388b402cd8e98f7eedbd to your computer and use it in GitHub Desktop.
Save BrendonKoz/b1df234fe3ee388b402cd8e98f7eedbd to your computer and use it in GitHub Desktop.
Automatic Dark Mode for Leaflet.js
// Leaflet JS - note the *className* attribute
// [...]

L.tileLayer('https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
    className: 'map-tiles'
}).addTo(map);

// [...]
/* Only the necessary CSS shown */

:root {
    --map-tiles-filter: brightness(0.6) invert(1) contrast(3) hue-rotate(200deg) saturate(0.3) brightness(0.7);
}

@media (prefers-color-scheme: dark) {
    .map-tiles {
        filter:var(--map-tiles-filter, none);
	}
}

/** The non-dark mode map will be untouched since it's not styled. **/
/**
    Source: https://github.com/pkrasicki/issviewer
    Discovered via: https://github.com/openstreetmap/openstreetmap-website/issues/2332
**/
@GeneralMine
Copy link

Works, thanks 🚀 👍

@BrendonKoz
Copy link
Author

👍 Glad it's worked for you too! Thanks to the original authors as well; glad I found it (and re-shared).

@britez13
Copy link

britez13 commented Dec 1, 2022

It also works with react-leaflet. Thanks for sharing!

@BrendonKoz
Copy link
Author

It should work with any version of leaflet that uses the original package source (up until leaflet itself changes their JS approach and/or named classes). Although I haven't used React-Leaflet, I'd have to presume that it is just a wrapper around the original.

Glad it worked for you though! 👍

@dskvr
Copy link

dskvr commented Jan 12, 2023

Works well, but noticed that there are lines between each tile that are prevalent when zoomed. In light mode, these lines are less prevalent. I believe it's a default background-color of a distant sibling, but have been unable to locate it. Thoughts?

@BrendonKoz
Copy link
Author

@dskvr Are you using the same tile layer I am above? Either I don't notice what you're referring to, or the map style I've chosen for my use doesn't seem to display this issue. Are you using the "hot" (Humanitarian) tile layer like I am in the gist? This may work with other map tile layers too, but I've only really tested it for use in this one.

@patrickdalla
Copy link

Hi, I was using a similar approach discovered by other means. But my project manager found it too CPU intensive.
Does any one know if there are tile server urls with already applied dark theme? It seems google has.

@BrendonKoz
Copy link
Author

I've found a couple, but both require some sort of paid subscription.

  1. https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png
  2. https://tile.jawg.io/dark/{z}/{x}/{y}.png

I didn't look into the subscription(s) as I'm not personally using them (nor will I spend time to research them), but it may lead you to some option. It is possible to generate your own tile maps and serve them yourself, though I suspect that unless you know you'll only be supporting a small geographic area (and intend to keep up with geographic updates/changes) that could be problematic too.

Depending on the device(s) that will be viewing the map, CPU should, under normal conditions, be minimal since modern web browsers take advantage of GPU rendering of CSS when available. This method is definitely a tradeoff of aesthetics and resources, however.

Here's a video of one person having CPU resource issues while using CSS' filter() properties. Always good to keep these scenarios in mind.

@carloskim123
Copy link

works for me too thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment