21

Mapbox doesn't fit to it's container. whay not?

This is the rendered html:

<div class="map mapboxgl-map" id="mapBox">
  <div class="mapboxgl-canvas-container">
    <canvas class="mapboxgl-canvas" style="position: absolute; width: 1920px; height: 277px;" tabindex="0" aria-label="Map" width="1920" height="277">
    </canvas>
  </div>
</div>

those 277px are the default I guess.

this is the js:

mapboxgl.accessToken = 'blabla';
  var map = new mapboxgl.Map({
    container: 'mapBox',
    style: 'mapbox://styles/mapbox/streets-v11',
    center: [-77.04, 38.907],
    zoom: 11.15
  });

this is the scss:

.map {
  grid-column: 1/-1;
  height: 100%;
  position: relative;
  canvas, .mapboxgl-canvas {
    height: 100%;
  }
}

If I add the ever so famous !important to the height: 100%; then it works but the map is stretched.

How do I have to do this?

KSPR
  • 2,212
  • 4
  • 29
  • 46
  • Probably because the canvas is absolutely positioned. Not sure why that is...it doesn't add to the parent's height that way. – Paulie_D Jul 23 '19 at 15:28
  • You should never need to style the canvas directly. What's the actual problem you're having? – Steve Bennett Jul 24 '19 at 14:52
  • tha canvas is not reponsive it does not fit to the height of the container. There are these inlined 227px which I don't know where they are coming from and in the mapbox doc's I can't find anything about reponsivenes. – KSPR Jul 28 '19 at 08:57

9 Answers9

45

I found the trick.

just add

map.on('load', function () {
    map.resize();
});

to the js so the map will resize to it's container

KSPR
  • 2,212
  • 4
  • 29
  • 46
  • 1
    this is Awesome❤ – Shahnad S Jan 19 '21 at 13:49
  • 3
    instead of map.on('load', function(){}) you can use map.on('render', function(){}) this will make the size take full container's size before map load because the map can load in small size and then it resizes to full size which creates a bad UI experience. While on render event it resizes before having things loaded – sultanmb26 Sep 16 '21 at 13:49
  • For those using react-map-gl check this out: https://stackoverflow.com/questions/71006426/react-map-gl-map-is-not-fullscreen-until-resizing-window – Greg Holst Nov 23 '22 at 22:28
  • @sultanmb26 Unfortunately the render event fires every time the map renders, not just at the start, which leads to me not being able to pan at all due to the lag... The DOMContentLoaded event may be a better one to listen to, see my answer https://stackoverflow.com/a/74611174 – Ethan Nov 29 '22 at 08:39
7

After hours trying to find a solution and trying solutions here on SO, I have finally understood how to make Mapbox fit its container. To make mapbox fit to it's container, without the need to set absolute height, it must be the immediate first child of a parent div. Mapbox cannot be the second, third or fourth child etc. Why? My guess is that mapbox-gl.css enters in conflict with custom css rules.

This works every single time :

<section class="map_box_container">
    <!--MAP-->
  <div id='map'></div>
</section>

This never works:

   <section class="map_box_container">
<div class="second_child">
        <!--MAP-->
      <div id='map'></div>
</div>
    </section>

CSS

.map_box_container{
  position: relative;
  height: 100% !important;
  width: 100% !important;
}

  #map {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100%;
  }

Update 2021

I'm using mapbox in a new project and it is my understanding that mapbox does not require its parent container to have any css to work.

HTML

<section class="map_box_container">
<!--MAP-->
<div id='map'></div>
</section>

CSS

#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
Grogu
  • 2,097
  • 15
  • 36
  • 1
    The best answer! – Marlon Abeykoon Sep 09 '20 at 07:49
  • Note that if you want the markers to remain intact, you'll want to set them also to absolute: `.mapboxgl-marker { position: absolute; top: 0; left: 0; }`. – shennan Nov 24 '20 at 15:49
  • Update 2021 is the correct answer imo. If the map parent is inside a grid, set its position to relative, then apply #map styles with absolute positioning. – Stephen May 03 '21 at 05:04
  • This is not a good answer at all. The CSS displayed here is pretty bad practice. In the early 2000 absolute positioning was acceptable for layouting but not in 2023. Also `!important` is to be avoided – KSPR Aug 11 '23 at 12:41
1

add this to your css

.mapboxgl-map {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100%;
    }

and { position: relative } to its parent div

  • 4
    this is ignored by the mapbox script – KSPR Jan 19 '20 at 17:29
  • .....it worked. Also fixed my problem of scroll wheel scrolling map instead of zooming in and out. Best answer. Although I didn't the parent position: relative since I already had it as absolute. – Diego Cuadros Apr 20 '21 at 01:50
1

This worked for me, and you don't get the visible lag before resizing like you do in the accepted answer:

document.addEventListener("DOMContentLoaded", () => map.resize());
Ethan
  • 3,410
  • 1
  • 28
  • 49
0
const [viewport, setViewport] = useState({
    width: '100%',
    height: 'calc(100vh - 162px)', // 162px is size height of all elements at the top of the map
    latitude: 0,
    longitude: 0,
    zoom: 12,
    bearing: 0,
    pitch: 0,
    transitionDuration: 2000,
    transitionInterpolator: new FlyToInterpolator(),
  });
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Canonne Gregory
  • 378
  • 4
  • 9
0

This one worked for me. It takes a while before it takes effect but its worth it.

map.on('load', function() {
    $('.mapboxgl-canvas').css('width', '100%');
    $('.mapboxgl-canvas').css('height', '100%');
    map.resize();
});
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
0

Pure CSS solution without absolute positioning.

New Method:

Add to your wrapper:

aspect-ratio: 1 / 1;

Play with the value if you want a rectangle (Ex: .9).

Old Method:

Each parent must have a height larger than 0. Check your dev inspector. For each container that renders a height of 0 add height: 100%;. Then for your map wrapper add these two CSS declarations to it:

height: 100%;
max-height: 500px;

Change 500 to whatever works in your media queries and you should be good.

Scott L
  • 533
  • 5
  • 9
0

2022

1- Update your map script add map.resize()

<script>
  map.on("load", () => {map.resize()
</script>

2- Update your html add tailwind class="aspect-square w-full h-full" or add style="aspect-ratio: 1 / 1":

<div id="map"
  class="aspect-square w-full h-full"
  style="aspect-ratio: 1 / 1;"
>
</div>
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
osama
  • 1
  • 2
-2

Only reliable way I've found is to use jQuery. In my case the map is in a tab that's not active when the page loads, so I execute the code when switching to the tab that holds the map.

var $ = window["$"];
$('.mapboxgl-canvas').css('width', '100%');
$('.mapboxgl-canvas').css('height', '100%');

EDIT: That works, but the map looks ugly and pixelated. I will probably go back to Google Maps.

Francis Ducharme
  • 4,848
  • 6
  • 43
  • 81