3

I would like to show a leaflet map inside a flex container in order to permit easy resizing of the map as other (initially hidden) elements in the parent are displayed/hidden. Here is what I am doing

  • I have a flex container set up with two div elements stacked in it - occupying equal heights by default
  • The bottom half contains an image
  • The top half contains the actual map which has to be created inside a dynamically added div element.
  • There is a third flex div element, infoBox which is hidden initially. The eventual idea being that when display:flexis set on infoBox it causes the other contents to shrink down (ideally disappear but it looks like Flexbox does not do that)

Where this idea is failing currently is that I simply cannot get the map to show in the first place. Examining the added imap element in the Chrome developer console reveals that its height is stuck at 0.

This almost certainly has something to do with the fact that I am using a flex container rather than a fixed height one. However, I am unable to find a way around the issue. How can I get this to work as intended?

var imap = document.createElement('div');
imap.id = 'imap';

document.getElementById('mapBox').appendChild(imap);
 var lmap = L.map('imap',{center:[51.510067,-0.133869],zoom:10});
#container
{
 display:flex;
 flex-direction:column-reverse;
 min-height:400px;
}

#picBox
{
 flex:5;
 background-image:url(https://placeimg.com/1000/1000/tech);
 background-size:cover;
 background-repeat:no-repeat;
 background-position:center;
}

#mapBox
{
 flex:5;
 position:relative;
 border:1px solid red;
}

#infoBox
{
 flex:20;
 border:1px solid blue;
 display:none;
}
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.css" rel="stylesheet"/>
<div id='container'>
<div id='infoBox'>Stackoverflow is really cool!</div>
<div id='picBox'>&nbsp;</div>
<div id='mapBox'>

</div>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
DroidOS
  • 8,530
  • 16
  • 99
  • 171

2 Answers2

2

The main problem here is your dynamically created div, with id imap.

It renders as a standard div, that take full width of its parent, but since it hasn't got any content (the map renders as an absolute positioned element), its height is 0.

You could make the mapBox a flex container, so the imap element you create with script will stretch and fill its parent.

Stack snippet

var imap = document.createElement('div');
imap.id = 'imap';

document.getElementById('mapBox').appendChild(imap);
 var lmap = L.map('imap',{center:[51.510067,-0.133869],zoom:10});
#container
{
 display:flex;
 flex-direction:column-reverse;
 min-height:400px;
}

#picBox
{
 flex:5;
 background-image:url(https://placeimg.com/1000/1000/tech);
 background-size:cover;
 background-repeat:no-repeat;
 background-position:center;
}

#mapBox
{
 flex:5;
 position:relative;
 border:1px solid red;
 
 display: flex;                    /*  added  */
}

#mapBox > div
{
 flex:1;                       /*  added, fill width of parent  */
 /*align-items: stretch;           is default, fill height of parent  */
}

#infoBox
{
 flex:20;
 border:1px solid blue;
 display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.css" rel="stylesheet"/>
<div id='container'>
<div id='infoBox'>Stackoverflow is really cool!</div>
<div id='picBox'>&nbsp;</div>
<div id='mapBox'>

</div>
</div>

Or change the script, so the map will use the mapBox element instead.

Stack snippet

 var lmap = L.map('mapBox',{center:[51.510067,-0.133869],zoom:10});
#container
{
 display:flex;
 flex-direction:column-reverse;
 min-height:400px;
}

#picBox
{
 flex:5;
 background-image:url(https://placeimg.com/1000/1000/tech);
 background-size:cover;
 background-repeat:no-repeat;
 background-position:center;
}

#mapBox
{
 flex:5;
 position:relative;
 border:1px solid red; 
}

#infoBox
{
 flex:20;
 border:1px solid blue;
 display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.1/leaflet.css" rel="stylesheet"/>
<div id='container'>
<div id='infoBox'>Stackoverflow is really cool!</div>
<div id='picBox'>&nbsp;</div>
<div id='mapBox'>

</div>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
2

If your map is initially hidden, and its container element is shown after some time (or after some interaction), you might need to run map.invalidateSize() when that happens.

See e.g. Leaflet map not displayed properly inside tabbed panel.

IvanSanchez
  • 18,272
  • 3
  • 30
  • 45