I try to apply a grayscale effect to the background of a map, but I don't want the upper layers of the map to be affected by the grayscale.
Naively, I applied a CSS filter on the canvas element:
filter: grayscale(1);
but of course everything on my map turned to gray :
I want to preserve the border of the city Aix-en-Provence green, but I want the background of the map to be gray.
Is it possible to somehow apply a grayscale to all layers behind one layer ?
No, it's not possible using CSS filters, as mapbox uses a single canvas element to draw all its layers. The only way to go about this is to modify the colors in the style of the map and change all color related prop values of the layers you want grayscal-ed to their grayscale equivalent. I'm pretty sure you'll find grayscale styles for mapbox.
In theory, since it's possible to fetch all layers of the map (and their order), and it's also possible to get the contents of its style object, this task could be automated, but it would need attention to detail and thorough testing.
Definitely not a one liner.
Most likely, it also won't work for external images (e.g: image layers or layers displaying sprites) used by the map, unless you replace those with grayscale alternatives, too.
Another approach, which might just work, would be to use the same technique as the mapbox-gl-compare plugin and have two maps overlapped. Obviously, in your case, you won't have the slider to toggle between them and the one on top would need to be mostly transparent, while the one below would be transformed using CSS filtering.
You'd think keeping two maps in sync in terms of panning, zooming (and, most importantly: rendering) wouldn't work but, as you can see in the plugin demo, it works quite well. All you have to figure out is how to make the map on top mostly transparent (it's a map style modification job - although easier, as this time you'd need to simply hide the layers, not change their color). Also note having the layers disabled will actually make the top map faster, so it looks like the right solution.