How to render leaflet map when in hidden "display: none;" parent

dsalaj picture dsalaj · Feb 5, 2016 · Viewed 7.5k times · Source

I am experiencing strange behaviour when displaying leaflet map on my page. Normally the map is rendered as expected and works well. However I want to display the map only when an error occurs in forms which I detect in javascript. So if I set the parent <div id="map"> to display: none; and show it later as needed, the tiles are not loaded (or only partially load and do not continue) and the map is strangely "dislocated" (not centred as defined in js).

My thought is that maybe the browser does not render the elements inside a display: none; parent?

I tried hiding the map with the $(document).ready(...) function but it made no difference. The same behaviour repeats as soon as I hide and show the map. I tested this on Firefox 44.0 and Chromium 48.0 and the behaviour is consistent.

Any tip would be helpful. Is this general behaviour for remotely loaded elements (ajax)?

Edit 1:

Now I know the solution and a workaround (see the answers bellow), but I am still unsure if this is a global behaviour for remotely loaded elements? Thanks for any explanation.

Edit 2:

See the accepted answer for explanation.

Answer

iH8 picture iH8 · Feb 5, 2016

What's happening is that your L.Map instance can not correctly calculate it's dimensions because of the display:none CSS rule. If it doesn't get the proper dimensions it doesn't know how many tiles to load and how to lay them out, it just loads none. XHR has nothing to do with it. The map doesn't know what to XHR, that's the problem.

After you've switched from display:none to display:block call the invalidateSize method on your L.Map instance. It will force the map to (re)render:

Checks if the map container size changed and updates the map if so — call it after you've changed the map size dynamically, also animating pan by default. If options.pan is false, panning will not occur. If options.debounceMoveend is true, it will delay moveend event so that it doesn't happen often even if the method is called many times in a row.

http://leafletjs.com/reference.html#map-invalidatesize