面图层盖住了线图层,调 zIndex 反而更糟
道路线被行政区面压在下面,设了 zIndex: 999 依旧没变,甚至整条线消失了。
现象
图层加入顺序是:面(行政区)→ 线(道路)→ 点(POI)。
实际渲染却是面压住了线,点又压在面上面。
给线图层加 { zIndex: 999 } 后,线彻底不见,
拖动地图时才偶尔闪一下。
原因
Leaflet 的 zIndex 不是图层之间的排序,而是同一个渲染器内部
的容器层级。默认情况下所有矢量图层共用同一个 SVG 渲染器,
zIndex 被渲染器忽略,真正决定顺序的是 addLayer 的先后。
设了 999 后,Leaflet 会给该图层单独创建一个渲染器(因为 pane 或
renderer 变化),新渲染器的 pane 默认 z-index 是 400,
反而落到了面图层下面。
OpenLayers 不同:图层顺序由 layer.getZIndex() 或加入 collection 的次序决定,
给 zIndex 赋值确实生效,但数字越大越靠上。
| 库 | 控制层级的方式 | zIndex 是否有效 |
|---|---|---|
| Leaflet | pane 或 bringToFront() | 跨 pane 有效,同 pane 内无效 |
| OpenLayers | layer.setZIndex(n) | 有效 |
| Mapbox GL | 样式里 layers 数组顺序 | 无 zIndex 概念 |
排查过程
- 在 Elements 面板看各图层的
.leaflet-pane与z-index。 - 检查代码里是否给多个图层设了不同
renderer或pane。 - 看加入顺序,Leaflet 同 pane 内后加的在上面。
- 给面图层设置
interactive: false后测试,排除点击事件干扰。
console.log(map.getPane('overlayPane').style.zIndex); // 400
// 自定义 pane 若没设 z-index,会和默认 pane 抢层级
document.querySelectorAll('.leaflet-pane').forEach(p =>
console.log(p.className, getComputedStyle(p).zIndex));
解决方案
用自定义 pane 明确分层,或直接调整加入顺序。 不要在同一 pane 内指望 zIndex 排序。
// 1. 建立三个专用 pane,层级写清楚
map.createPane('areas');
map.getPane('areas').style.zIndex = 410;
map.createPane('roads');
map.getPane('roads').style.zIndex = 420;
map.createPane('pois');
map.getPane('pois').style.zIndex = 430;
L.geoJSON(areaData, {
pane: 'areas',
style: { fillOpacity: 0.35, color: '#1a6fd4', weight: 1 }
}).addTo(map);
L.geoJSON(roadData, {
pane: 'roads',
style: { color: '#e8590c', weight: 3 }
}).addTo(map);
L.geoJSON(poiData, { pane: 'pois' }).addTo(map);
// OpenLayers:zIndex 直接生效
const roads = new VectorLayer({ source: roadSource, zIndex: 20 });
const areas = new VectorLayer({ source: areaSource, zIndex: 10 });
map.addLayer(areas);
map.addLayer(roads);
验证
道路线完整压在行政区面之上,点击道路能命中线图层;
map.getPane('roads').style.zIndex > map.getPane('areas').style.zIndex。
const zi = n => Number(map.getPane(n).style.zIndex);
console.assert(zi('roads') > zi('areas'), '层级仍不对');
console.assert(zi('pois') > zi('roads'), '点被压住');
适用版本
| 库 | 版本 | 说明 |
|---|---|---|
| Leaflet | 1.9.x | 默认 pane:tilePane 200、overlayPane 400、markerPane 600 |
| OpenLayers | 6.x ~ 9.x | setZIndex 生效 |
| Mapbox GL JS | 2.x / 3.x | 用 moveLayer(id, beforeId) 调整 |
经纬志(2026)。《面图层盖住了线图层,调 zIndex 反而更糟》。https://www.jingweizhi.com/cookbook/layer-order-cover.html(访问日期 2026-11-03)。