How can I change the icon for the Leaflet layers control icon in my webpage, when there are more than one such layers control?
The goal is to have different icons here:

The code for that looks like:
var layers1 = L.control.layers(...).addTo(map);
var layers2 = L.control.layers(...).addTo(map);
If I change the control's icon via CSS, it changes in all layers controls.
I had the same problem and I found a much faster solution.
I simply overrided the background-image attribute of the specific Layer Control from the styles.css of my app in this way:
.leaflet-top.leaflet-right .leaflet-control-layers:nth-child(3) .leaflet-control-layers-toggle {
background-image: /*set you value*/
}
In my case the second Layer Control was the third child (Toolbar, Layer Control 1 and Layer Control 2), so change that index to get the right Control. Hope it helps!
<Edit 2020: fixed typo in code>
On one hand, I suggest you have a look at the Leaflet list of plugins for layer switchers. There might be one that fits your use case better than two default L.Control.Layers with different icons.
On the other hand: The layers control icon is supplied by CSS, in this line:
.leaflet-control-layers-toggle {
background-image: url(images/layers.png);
width: 36px;
height: 36px;
}
That CSS class name comes from the _initLayout private method of L.Control.Layers:
_initLayout: function () {
var className = 'leaflet-control-layers',
// [snip]
var link = this._layersLink = DomUtil.create('a', className + '-toggle', container);
// [snip]
}
Note how the toggler HTMLElement, which holds the image, is stored as a private property this._layersLink. That HTMLElement can be manipulated afterwards.
With this knowledge, we can create a subclass of L.Control.Layers,
like:
L.Control.Layers.TogglerIcon = L.Control.Layers.extend({
options: {
// Optional base CSS class name for the toggler element
togglerClassName: undefined
},
_initLayout: function(){
L.Control.Layers.prototype._initLayout.call(this);
if (this.options.togglerClassName) {
L.DomUtil.addClass(this._layersLink, togglerClassName);
}
}
});
And then create two of these layers controls passing that new option, e.g.:
var layers1 =
new L.Control.Layers.TogglerIcon(..., ..., {togglerClassName: 'layers-flowers'});
var layers2 =
new L.Control.Layers.TogglerIcon(..., ..., {togglerClassName: 'layers-cars'});
And then have some CSS for their icons, e.g.:
.layers-flowers {
background-image: url(images/layers-flowers.png);
width: 36px;
height: 36px;
}
.layers-cars {
/* idem */
}
Please note that instead of adding a CSS class, one can also modify the HTMLElement's inside the code, e.g.:
_initLayout: function(){
L.Control.Layers.prototype._initLayout.call(this);
if (this.options.backgroundImageUrl) {
this._layersLink.style.backgroundImage = this.options.backgroundImageUrl;
}
}
Albeit that might need a bit more precise fiddling.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With