Skip to content

Instantly share code, notes, and snippets.

@BrendonKoz
Last active April 27, 2025 20:02
Show Gist options
  • 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
**/
@carloskim123
Copy link

works for me too thanks

@fitsum
Copy link

fitsum commented Aug 21, 2024

hits the spot, can worth with this. thank you 🤙🏾

@bloodykheeng
Copy link

bloodykheeng commented Apr 27, 2025

map failed to work with tailwind if i switch the theme map doesnt switch layer unless i change page and come back
className dark:map-tiles is failing

this is failing

        <TileLayer
                                    className="dark:map-tiles"
                                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                                    attribution='&copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                                />

anyone with a solution on how i can archieve dark mode light mode switching with tailwind im using nextjs 15

<MapContainer
                                center={[1.3733, 32.2903]}
                                zoom={7}
                                scrollWheelZoom={true}
                                attributionControl={false}
                                whenReady={handleMapCreated}
                                fullscreenControl={true}
                                // whenCreated={handleMapCreated}
                                style={{ height: "80vh", width: "100%", zIndex: "0" }}
                                ref={mapRef}
                            >
                                {/* <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution='&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors' /> */}


                                <TileLayer
                                    className="dark:map-tiles"
                                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                                    attribution='&copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                                />

                                <LayersControl>
                                    <BaseLayer checked name="OpenStreetMap">
                                        <TileLayer className="dark:map-tiles" url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' />
                                    </BaseLayer>

                                    <BaseLayer name="Terrain View">
                                        <TileLayer url="https://{s}.google.com/vt/lyrs=p&x={x}&y={y}&z={z}" maxZoom={20} subdomains={["mt1", "mt2", "mt3"]} />
                                    </BaseLayer>

                                    <BaseLayer name="Satellite View">
                                        <TileLayer url="https://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}" maxZoom={20} subdomains={["mt1", "mt2", "mt3"]} />
                                    </BaseLayer>
                                    <BaseLayer name="Hybrid View">
                                        <TileLayer url="https://{s}.google.com/vt/lyrs=h&x={x}&y={y}&z={z}" maxZoom={20} subdomains={["mt1", "mt2", "mt3"]} />
                                    </BaseLayer>
                                </LayersControl>

                                {filteredDistrictsGeoJson && <GeoJSON data={filteredDistrictsGeoJson} onEachFeature={onEachDistrict} style={geoJsonDistrictStyles} />}
                                {filteredRegionsGeoJson && <GeoJSON data={filteredRegionsGeoJson} onEachFeature={onEachDistrict} style={geoJsonDistrictStyles} />}

                                <MarkerClusterGroup chunkedLoading>
                                    {getProjectsWithReportsQuery.data?.data?.data.map((project: any, index: number) => {
                                        // Parse latitude and longitude values
                                        const latitude = parseFloat(project?.latitude);
                                        const longitude = parseFloat(project?.longitude);

                                        // Check if latitude and longitude are valid numbers before creating the Marker
                                        if (isNaN(latitude) || isNaN(longitude)) {
                                            // console.warn(`project map Skipping marker at index ${index} due to invalid coordinates: (${project.latitude}, ${project.longitude})`);
                                            return null; // Skip this marker
                                        }

                                        return (
                                            <Marker key={index} position={[latitude, longitude]}>
                                                <Popup>{createMarkerPopup(project)}</Popup>
                                            </Marker>
                                        );
                                    })}
                                </MarkerClusterGroup>

                                <MapPrint />
                            </MapContainer>
                        </div>
                    </>

here is the css ive put in my globals.css

/* make the react leaflet map dark moded */
/* got the solution here https://gist.github.com/BrendonKoz/b1df234fe3ee388b402cd8e98f7eedbd */
: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);
  }
}

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