13

BACKGROUND: I have a desktop browser app that uses mapquest with the leaflet js plugin. I am using divIcon class for the markers, which allows me to use custom HTML and styling for the markers. Each divIcon marker also contains a hidden div that displays when the marker is hovered over (using :hover class). I am using neither the default marker or default popup built into leaflet, because custom html gives much better control over styling.

PROBLEM: When the popup is showing, any other markers on the map show on top of the popup, instead of underneath. I have tried setting z-index of the popup div to a really higher number, but it does not help.

WHAT IS EXPECTED: When you hover the mouse over an icon, the markers should be behind the popup, not in front.

THIS IS NOT A DUPLICATE QUESTION: This question is not the same as this one. That question was about having the default leaflet popups stay on top of a custom div that is outside of the map z-index context. This question is about a custom mouseover popup (not the default popup) staying above other markers. Plus, my solution is completely different from the admittedly javascript "hack" put forward as a workaround.

WORKING EXAMPLE OF PROBLEM: https://jsfiddle.net/mrrost/py2bqw7j/

Here is what divIcon code with custom marker/popup looks like:

var pin = L.divIcon({ 
  html: `
    <div class='marker'>
        Pin
        <div class='popup'>
        Marker info. Other markers WILL BE on top of this div.
        This is BAD and a PROBLEM.
      </div>
    </div>
  `,
});

This most important css definitions:

#map {
    position: fixed;
}

/* hide default leaflet pin; div.popup is put inside here */
.leaflet-marker-icon {
    border: 0; margin: 0; padding: 0;
}    

div.popup {
  display: none;
  position: absolute;
}

div.marker:hover div.popup {
  display: block;
}
Community
  • 1
  • 1
Mike
  • 317
  • 2
  • 11
  • Possible duplicate of [z-index not working as intended](http://stackoverflow.com/questions/34270421/z-index-not-working-as-intended) – nothingisnecessary Apr 09 '17 at 17:38
  • 3
    No, this is not a duplicate. That question was about having the default leaflet popups stay on top of a custom div, outside this map. This post is about a custom mouseover popup (not the default popup) stay above other markers. Plus, my solution is completely difference from the javascript hack used on that question. – Mike Apr 10 '17 at 04:31
  • 4
    Possible duplicate of [How can I show child element above parent element AND siblings of the parent element?](http://stackoverflow.com/questions/11175833/how-can-i-show-child-element-above-parent-element-and-siblings-of-the-parent-ele) – TylerH Apr 17 '17 at 15:04

2 Answers2

11

The solution was to better understand how z-indexing works. The popup is set inside the marker (to make is work with just css :hover), so it is the child of the parent marker element. Z-index is inherited from parent elements, and child elements cannot have a z-index higher than its parent. That's just how z-indexing works. So, setting z-index on the popup element is ignored by the browser, because leaflet has set a z-index for the marker.

The fix was to use a css rule that tells the browser to lower the z-index of all other markers, when a marker is hovered over:

.leaflet-marker-icon:not(:hover) {
  z-index: 0 !important;
}

See here for a full working example:

https://jsfiddle.net/mrrost/tdr45764/

Mike
  • 317
  • 2
  • 11
  • 2
    "child elements cannot have a z-index higher than its parent" This is not correct. Descendant elements can have higher z-index values than their ancestor elements. In fact that's the expected logical progression of z-index values. You would not typically want a child to be behind/before its parent on the z axis. – TylerH Apr 17 '17 at 14:53
  • 1
    Specifically, it's higher *within the stacking context established by the parent*. I think you are getting your interpretation from http://stackoverflow.com/revisions/11330567/1 which incorrectly interpreted [this answer](http://stackoverflow.com/a/3199134/2756409). I've [updated the former answer](http://stackoverflow.com/revisions/11330567/2) to more accurately reflect what's going on. – TylerH Apr 17 '17 at 15:03
  • 3
    With that being said, you are right that your question is not a dupe of the one suggested on April 9th. However, it *is* a dupe of http://stackoverflow.com/questions/11175833/show-child-element-above-parent-element-and-siblings-of-parent – TylerH Apr 17 '17 at 15:04
1

Leaflet markers have a riseOnHover property, which makes the marker appear on top of other markers on hover.

const marker = L.marker([50.5, 30.5], { riseOnHover: true }).addTo(map);

See https://leafletjs.com/reference-1.6.0.html#marker-riseonhover

Joonas
  • 892
  • 6
  • 18