19

I want open a popup on bottom of my marker icon in Leaflet.

my code:

var mymap = L.map('mapid').setView([51.505, -0.09], 13);

L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw', {
    maxZoom: 18,
    attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
    '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
    'Imagery © <a href="http://mapbox.com">Mapbox</a>',
    id: 'mapbox.streets'
}).addTo(mymap);

var lati = 51.51;
var longi = -0.09;

var popupLocation1 = new L.LatLng(lati, longi);
var popupContent1 = 'This is a nice popup';

popup1 = new L.Popup();
popup1.setLatLng(popupLocation1);
popup1.setContent(popupContent1);

var m1 = L.marker([ lati, longi ]).addTo(mymap);

m1.bindPopup(popup1);

m1.openPopup();

So I get a popup on top of my marker.

I want get a popup on bottom like:

enter image description here

4
  • Check out this Q/A, stackoverflow.com/questions/27144334/…
    – artwork21
    Commented May 18, 2016 at 11:52
  • on your link is no working solution. Perhaps the comment is true: "what you could do is hook into the click of the marker and draw your own popup with custom code" No simple way for bottom popup?
    – Gerd
    Commented May 18, 2016 at 13:09
  • 1
    The current situation is the same as in artwork21's comment link, regarding your question for popup below the marker. See FranceImage's answer (stackoverflow.com/a/27144900/5108796) with proposed plugin. You could use that plugin or get inspiration from it to build your own custom popup.
    – ghybs
    Commented May 18, 2016 at 13:38
  • Can't we do it in the CSS positioning of the popup itself? Because by default that's referencing off the bottom, if we switch to the top then it will be correct [up to a fixed offset] regardless of the fonts/fontsizes/lineheights chosen and number of lines of text? I'm probably overlooking something. Commented Dec 16, 2019 at 20:16

4 Answers 4

6

You can specify the offsets by using the popupAnchor options, but not where you would expect it. First, you need to specify an icon like this:

var myIcon = L.divIcon({ popupAnchor: [0, -30] });

You can then use this icon in your marker options:

var marker = L.marker(location, {
                 icon: myIcon
             }).bindPopup(function (marker) {...}); //Shortened

Now your popup opens up 30 px above your marker. This is not exactly what you asked for as you also need to place the little arrowish triangle on the top of your popup, but I think it's still worth mentioning.

1
  • Same problem as with the more recent [29 Aug 2019] answer by @Johannes: This offset is wrong as fast as there's a second or further line of text in the popup; or changes in CSS (font-size, font, line-height, padding, margin, popup size, ...). Hence the original answer "there is no native solution" stands. Commented Dec 16, 2019 at 20:14
5

I know that this is an old question, but you do not need to take the detour @Robert described in his reply.

As Popup is inheriting from DivOverlay, you can set the offset option directly when initializing the Popup:

    var popup = L.popup({
        offset: [0, -30]
    })
      .setLatLng(location)
      .setContent("Test Text")
      .openOn(mapId);

Read the docs: https://leafletjs.com/reference-1.5.0.html#popup

1
  • The problem with this approach is that you have magic numbers for the offset: If the font-size or font or even line-height changes, the offset is bad. More problematically, if some popups contain a second (or third, etc) line of text, they're now a full line-height (or two, etc) too high, and probably completely overlapping the marker and its neighbourhood. You'll probably need to measure the height of the text inside the popup and change the offset dynamically and move it using JS during/after rendering; or have very fixed CSS and calculate it during your leaflet map before adding the marker. Commented Dec 16, 2019 at 20:11
3

There is no native leaflet solution.

One other way is use https://github.com/erictheise/rrose

Nice Demo:

http://jsfiddle.net/asleepwalker/6m81vtad/

1

This seems to be possible just in CSS. Below I'm overriding (with !important) just three CSS elements, and adding one :before pseudo-element. I'm essentially first lining up the popup with the top instead of bottom, where 55px just depends on your chosen marker, and personal taste.

I then move the popup's "tip" similarly from bottom to top:0px, and discover it's not made using the "normal" trick (that is: first position on the bubble's edge a 0x0-sized pseudo-element with a thick transparent border, then colour that element's opposite border of where you want to point; in our case, the bottom-border). Instead it seems to be made from a rectangle rotated in from somewhere top-left (maybe: because it forces the browser to use the GPU and hence accelerates everything?) and I don't get the point (pardon the pun) well enough (my tip is in the right place but invisible); so I just remove the box-shadow that's now in the wrong place and leave it all as-is --- anyone who understands the "old tip" please adjust that.

So instead I make my own tip, with the "normal" process (if you're unsure, change the four border colours below, instead of 3x transparent and 1x white --- e.g. border-bottom-color: blue; border-left-color: green; border-top-color: yellow' border-right-color: red).

#map {
   position: absolute;
   top: 0;
   right: 0;
   left: 0;
   bottom: 0;
   z-index: 0;
}
.leaflet-popup {top: 55px !important;}
/* Here I move the "tip" to the right location, but didn't succeed in making it visible. So I just remove the box-shadow and leave it: */
.leaflet-popup-tip-container {
   top: 0px !important;
}
.leaflet-popup-tip {
   box-shadow: none !important;
}
.leaflet-popup:before 
    {
    content: "";
    position: absolute;
    border: 13px solid transparent;
    border-bottom-color: white;
    bottom: 0px;
    margin-left: -13px;
}

As this JSFiddle demonstrates, no problem with different popup-sizes (different width, different textheight) if you try both markers.

All in all this seems robust against updates in Leaflet as the items I'm overriding don't seem likely to change.

1
  • any way to show the popup outside of the map container if the container is small, i.e, 100px? Commented Nov 23, 2020 at 15:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.