OpenLayers - Grayscale, dark maps and more with CSS Filters

This week, I needed to render a simple map with some markers on it, and I felt that it would be great to have it shown in grayscale. While looking for that, I stumbled on the weird and wonderful world of CSS filters and how they can be used to style web maps.

Getting it Working

This can be really simple. In your CSS styles, add a class that has a filter, e.g., ol_bw and we assign it to the map when we create it.

.ol_bw {
    filter: grayscale(100%);
}

We provide the class name when we create the map as below:

layers: [
    new ol.layer.Tile({
        source: new ol.source.OSM(),
        className: 'ol_bw'
    })
]

This gives us a map that looks like this now.

You can see this online at http://openlayers-recipes.onghu.com/02_grayscale-maps/index.html and see all the source in the openlayers-recipes GitHub repository at https://github.com/mohits/openlayers-recipes/blob/main/docs/02_grayscale-maps/index.html

Playing with Filters

This section is just filled with outputs from using different filters to inspire you to try different things.

Not fully grayscale

The grayscale filter takes a percentage as a parameter. So, you can turn down how grey it gets. Let’s change this to 80% and that gives us this.

.ol_bw {
    filter: grayscale(80%);
}

Darkening the grayscale map

CSS has a brightness filter that takes a parameter which if below 1.0 darkens the image and brightens it above 1.0. So, you can get a darker grayscale by doing this.

.ol_bw {
    filter: grayscale(100%) brightness(0.9);
}

Brightening the default map

You could try to brighten the default OSM map by doing this:

.ol_bw {
    filter: brightness(1.15);
}

Going Dark

A simple trick to go dark is to invert the colours – black becomes white, and white becomes black, and so on.

.ol_bw {
    filter: invert(100%);
}

That does not look great. The trick to getting better is to also do a hue-rotate on this by 180 degress. The filter and the result are below.

.ol_bw {
    filter: invert(100%) hue-rotate(180deg);
}

Admittedly, that looks a lot better!

Here’s the last one – this brightens the map a bit before inverting it and rotating the hues.

.ol_bw {
    filter: brightness(1.1) invert(100%) hue-rotate(180deg) ;
}

One Last Note

You should be aware that what we did up till now was only to apply the CSS filter to the OSM map. You could apply it to anything – the whole page (apply it at the body) or the entire map container. If you did that, it would apply the filter to all things in the map – including markers, overlays, and so on. If you do that, remember to remove the filter className from the OL map… otherwise, the filters will apply one after the other (and 2 inverts will come back to the same place, for example).

Conclusion and Links

You can see the grayscale page live on my new site and the raw HTML file code is available from the mohits/openlayers-recipes repository on GitHub and this specific page is at https://github.com/mohits/openlayers-recipes/blob/main/docs/02_grayscale-maps/index.html

I’m not a designer and I’m sure that shows in the samples above. However, I do hope that this gives you some ideas on using just CSS for styling the map differently. I found the information from a number of sources and some experimentation and these are some of the main links.

Feel free to share the post (you can start a conversation or tag me as @onghu on X or on Mastodon as @onghu@ruby.social ) or leave a comment below, especially if you have other filters that you find useful.

comments powered by Disqus