经纬志
首页 / 实战手册 / Leaflet 容器与图层

flex 布局里地图高度为 0,只剩一条灰边

先看结论

页面顶部是标题栏,下面留一格放地图,结果地图只有几个像素高,瓦片挤成一条线。

最后验证 2026-11-03 · 多技术栈 · 更新 2026-10-29 · 引用本文

现象

地图容器的边框能看到,但高度几乎为零。打印尺寸得到 0:

console.log(map.getSize());
// Point {x: 1280, y: 0}

map.getCenter() 的经纬度是对的,缩放级别也对, 只是可视区域高度为零,任何瓦片都落不进视野。

原因

地图容器写了 height: 100%,但父级是 flex 布局且没有确定高度。 百分比高度在“父级高度由内容决定”的情况下无法解析,浏览器按 auto 处理, 容器里又没有内容,最终高度就是 0。

另一种情况是父级 flex: 1,但子项默认 min-height: auto, 被内部绝对定位的元素撑得无法收缩,或者反过来被压成 0。

排查过程

从地图容器向上逐级打印 clientHeight,找到第一个为 0 的层级:

var el = document.getElementById('map');
var node = el;
while (node && node !== document.documentElement) {
  console.log(node.tagName, node.className, node.clientHeight, getComputedStyle(node).display);
  node = node.parentElement;
}

解决方案

CSS 上给出一条确定的高度链。html、body 到主容器都要有高度, flex 子项补 min-height: 0:

html, body {
  height: 100%;
  margin: 0;
}
.layout {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.layout .header {
  flex: 0 0 56px;
}
.layout .map-wrap {
  flex: 1 1 auto;
  min-height: 0;          /* 允许收缩到剩余空间 */
  position: relative;
}
#map {
  position: absolute;
  inset: 0;
}

容器尺寸在初始化之后才确定时(例如抽屉展开、标签页切换), 必须通知 Leaflet 重新计算:

var map = L.map('map', { center: [39.907, 116.391], zoom: 11 });
L.tileLayer('https://tile.example.cn/{z}/{x}/{y}.png', {
  maxZoom: 18,
  attribution: '© Example'
}).addTo(map);

// 容器尺寸变化后
var ro = new ResizeObserver(function () {
  map.invalidateSize({ animate: false });
});
ro.observe(document.getElementById('map'));

在隐藏面板里创建地图时,等可见再初始化,避免一开始就按 0 尺寸绘制:

var panel = document.querySelector('#map-panel');
var observer = new MutationObserver(function () {
  if (panel.clientHeight > 0) {
    observer.disconnect();
    map.invalidateSize();
  }
});
observer.observe(panel, { attributes: true, attributeFilter: ['style', 'class'] });

验证

map.getSize() 的 y 值等于实际容器高度。 打开页面后瓦片铺满整个区域,不再只有顶部一条。 拖动窗口改变高度,地图跟随变化且瓦片不拉伸。

最小改动:只给 #map { height: 100vh } 也能立刻显示, 但在有标题栏的布局里会超出视口,出现滚动条。 正确做法是让容器高度来自 flex 布局,而不是写死视口高度。

引用本文

经纬志(2026)。《flex 布局里地图高度为 0,只剩一条灰边》。https://www.jingweizhi.com/cookbook/leaflet-flex-height-zero.html(访问日期 2026-11-03)。