Mapbox-gl height 100%
Asked Answered
Y

9

26

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?

Yarndyed answered 23/7, 2019 at 14:46 Comment(3)
Probably because the canvas is absolutely positioned. Not sure why that is...it doesn't add to the parent's height that way.Tumbler
You should never need to style the canvas directly. What's the actual problem you're having?Atwater
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.Yarndyed
Y
49

I found the trick.

just add

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

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

Yarndyed answered 29/7, 2019 at 7:21 Comment(4)
this is Awesome❤Adellaadelle
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 loadedDispirited
For those using react-map-gl check this out: #71006926Gerenuk
@Dispirited 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 stackoverflow.com/a/74611174Billon
T
8

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%;
}
Transubstantiate answered 15/1, 2020 at 4:16 Comment(4)
The best answer!Zurheide
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; }.Haemagglutinate
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.Hamburger
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 avoidedYarndyed
B
2

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());
Billon answered 29/11, 2022 at 8:37 Comment(0)
A
1

add this to your css

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

and { position: relative } to its parent div

Algin answered 30/7, 2019 at 22:27 Comment(2)
this is ignored by the mapbox scriptYarndyed
.....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.Gusman
V
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(),
  });
Ventilation answered 4/3, 2021 at 19:47 Comment(0)
K
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();
});
Keifer answered 5/1, 2022 at 16:1 Comment(0)
B
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.

Biochemistry answered 22/5, 2022 at 3:31 Comment(0)
A
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>
Absenteeism answered 15/11, 2022 at 11:51 Comment(0)
T
-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.

Toothpick answered 25/4, 2020 at 20:6 Comment(1)
This does not answer the question. The remark about Google Maps is not relevant.Norry

© 2022 - 2024 — McMap. All rights reserved.