1
votes

I am rendering a map using Mapboxgl, Bootstrap 4 and React.

I need the map to take 100% of the height of the page and to display in the first column of a two column grid.

However, when using React, the width of the map extends over to 100% of the width of the row - overlapping underneath the 2nd column.

The best thing would be to check my examples on jsfidle to understand what I mean.

Map correctly showing (when using pure HTML and no React) https://jsfiddle.net/apphancer/jhxy5c63/

Map showing width issue (when using React) https://jsfiddle.net/apphancer/9g71ovn6/

In order to have the 100% height working I am using this CSS:

.map-wrapper {
    position: fixed;
    width: 100%;
    height: 100%;
}

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

I suspect this might have something to do with how the map gets rendered with React as the problem does not happen when using the pure HTML solution.

Is anyone able to point in the right direction?

HTML

<div id="app"></div>

CSS

body, html {
    height: 100%;
}

#app, .row, .col-9 {
    height: 100%;
}

.col-3 {
    background-color: rgba(0, 0, 0, 0.5);
    border: 1px solid red;
}

.map-wrapper {
    position: fixed;
    width: 100%;
    height: 100%;
}

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

JS

mapboxgl.accessToken = 'pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4M29iazA2Z2gycXA4N2pmbDZmangifQ.-g_vE53SD2WrJ6tFX7QHmA';

class Application extends React.Component {
    componentDidMount() {
        const map = new mapboxgl.Map({
            container: 'map', // container id
            style: 'mapbox://styles/mapbox/light-v9', // stylesheet location
            center: [13.392, 52.523], // starting position [lng, lat]
            zoom: 9 // starting zoom
        });
        map.addControl(new mapboxgl.NavigationControl());
        map.resize(); // tried with this to see if it would help
    }

    render() {
        return (
            <div className="row no-gutters">
                <div className="col-9">
                    <div className="map-wrapper">
                        <div ref={el => this.mapContainer = el} id="map"/>
                    </div>
                </div>
                <div className="col-3">
                    2 of 2
                </div>
            </div>
        )
    }
}

ReactDOM.render(<Application/>, document.getElementById('app'));
3

3 Answers

2
votes

If you use position fixed with 100% width in wrapper, it will cover all width. But if you set position to relative, it will cover just remaining width.

.map-wrapper {
    position: relative;
    width: 100%;
    height: 100%;
}

This worked in your react-jsfiddle. Please try.

1
votes

If you are using position fixed in your project you can cover whole area so for that you have 2 solution

1st solution

give 75% width to the #map so it will behave like col-9 and no need to give position: absolute;

#map {
    width: 75%;
    height: 100%;
}

2nd Solution

give it relative position to the parent of your element so it cant leave it area, for that you can change position: fixed to position: relative

.map-wrapper {
    position: relative;
    width: 100%;
    height: 100%;
}

both solution is good solution but i prefer 2nd solution, from my side.

0
votes

const [viewport, setViewport] = useState({ width: '100%', height: 'calc(100vh - 162px)', // 162px is size height of all elements on top of map latitude: 0, longitude: 0, zoom: 12, bearing: 0, pitch: 0, transitionDuration: 2000, transitionInterpolator: new FlyToInterpolator(), });