首页 / 实战手册 / 瓦片
瓦片之间出现 1 像素白线,缩放后像蛛网
先看结论
每张瓦片都完整加载了,但拼起来满屏细白线,缩放级别越小越明显。
现象
在 2560×1440 的屏幕上,瓦片拼接处可见 1 像素宽的浅白色缝隙, 采用深色影像底图时尤其明显。放大到 18 级缝隙变少,缩到 10 级几乎成网状。
截图放大后可以确认缝隙宽度正好 1 个 CSS 像素, 且缝隙位置随地图平移而移动。
原因
三个因素叠加会导致亚像素缝隙:
- 地图容器的宽高不是瓦片尺寸的整数倍,瓦片定位出现小数像素。
- 浏览器对
transform: translate3d(x, y, 0)做抗锯齿,边缘被半透明化。 - 页面设置了
transform: scale()或浏览器缩放(110%、125%), 导致实际设备像素比与tileSize不匹配。
Leaflet 默认的瓦片定位带小数,配合硬件加速就会出现这条缝。
排查过程
- 把浏览器缩放到 100%,看缝隙是否消失。消失则为缩放导致。
- 在控制台读
layer.getContainer().style.transform,看是否有小数。 - 检查地图容器宽高:宽 1024、高 768 是整数倍关系,宽 1023 就会出现半像素。
- 检查页面是否对地图外层元素做了
scale或zoom。
console.log(layer.getContainer().style.transform);
// translate3d(1023.5px, 767.5px, 0px) <- 半像素,必出缝
console.log(map.getSize()); // Point(1023, 767) 不是 256 的整数倍
解决方案
三种手段按副作用从小到大:先给瓦片容器加 1 像素外扩, 再对齐容器尺寸,最后调整渲染参数。
/* 1. 让瓦片比格子大 1 像素,缝隙被覆盖 */
.leaflet-tile {
width: 257px !important;
height: 257px !important;
}
/* 2. 关闭瓦片层的硬件加速,避免小数像素抗锯齿 */
.leaflet-tile-container {
will-change: auto;
transform-style: flat;
}
// 3. 让容器尺寸为 256 的整数倍
const el = document.getElementById('map');
const w = Math.floor(el.clientWidth / 256) * 256;
el.style.width = w + 'px';
// 4. OpenLayers:给瓦片像素比留余量
new TileLayer({
source: new XYZ({ url: '...', tilePixelRatio: 1 }),
preload: 2
});
高分屏要区分 tileSize 与 detectRetina。
使用 512 像素瓦片时把 tileSize 设为 512,
并关闭 detectRetina,否则 Leaflet 会按 256 布局,缝隙翻倍。
验证
在深浅两种底图上各平移 10 秒,截图像素级检查,拼接处不再有连续白线; 切换浏览器缩放 100%、110%、125% 均正常。
console.assert(!/\.\d/.test(layer.getContainer().style.transform), '仍存在小数像素定位');
// 容器尺寸校验
console.assert(map.getSize().x % 256 === 0 || map.getSize().x % 512 === 0, '容器宽非瓦片整数倍');
适用版本
| 库 | 版本 | 说明 |
|---|---|---|
| Leaflet | 1.7 ~ 1.9 | 默认小数定位,需 CSS 或尺寸对齐 |
| OpenLayers | 6.x ~ 9.x | preload 与 tilePixelRatio 影响缝隙 |
| Chrome / Edge | 90 及以上 | 硬件加速下抗锯齿更明显 |
经纬志(2026)。《瓦片之间出现 1 像素白线,缩放后像蛛网》。https://www.jingweizhi.com/cookbook/tile-seam-gap.html(访问日期 2026-11-03)。