Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Space between tiles on fractional zoom levels #3575

Open
Eschon opened this issue Jun 30, 2015 · 194 comments · May be fixed by #6234, #6543 or #6240
Open

Space between tiles on fractional zoom levels #3575

Eschon opened this issue Jun 30, 2015 · 194 comments · May be fixed by #6234, #6543 or #6240

Comments

@Eschon
Copy link
Contributor

Eschon commented Jun 30, 2015

Note

This issue now has 150+ comments, most of which are concerned with hacky workarounds. I've compiled a list of a few comments that are discussing potential solutions:

(See also #3575 (comment).)

Relevant browser bugs, filed by @hyperknot:


(Also, mix-blend-mode is now used to alleviate the tile gaps in Chromium-based browsers: #8891.)

/@Malvoz

screen shot 2015-06-30 at 14 39 12

As the screenshot shows there is a small space between the tiles. This happens to me on fractional zoom levels in Safari, Chrome and Opera. It seems like this was fixed in #2377 but later removed in 3ccbe5b in favour of better performance.

I tried reimplementing the fix to see the performance impact myself and it was pretty bad furthermore it didn't even fix the problem for Chrome.

Does anyone have an idea how this can be fixed? Fractional zoom levels would be a great feature for our app but as long as this bug remains we can't really use them.

Edit: I set up a jsFiddle that shows the problem: http://jsfiddle.net/Eschon/pw9jcjus/1/

@mourner
Copy link
Member

mourner commented Jun 30, 2015

No idea. :( Although I only saw the problem in Safari, — Chrome/Opera worked fine.

@IvanSanchez
Copy link
Member

Does anyone have an idea how this can be fixed?

I have an idea, but it's linked to the words "radical" and "experimental":

https://github.com/IvanSanchez/Leaflet.gl

One of the things I discovered is that textures have to be clamped. i.e. if this line is removed : https://github.com/IvanSanchez/Leaflet.gl/blob/master/src/core/GlUtil.js#L74 slivers ("spaces between tiles") appear (as the texture wraps around the triangle and half a pixel of the other side of the tile is shown). So, my educated guess is that Webkit is antialiasing half a pixel on the edge of each image.

As of now, the tilelayer triangles form a complete mesh that is rendered without slivers... but the words "experimental" will be all over that for the time being.

@Eschon
Copy link
Contributor Author

Eschon commented Jun 30, 2015

@mourner It has a stronger effect in Safari but it is also visible in Chrome.
screen shot 2015-06-30 at 15 42 07

@IvanSanchez Wow nice work, but I don't think that I can use that (yet).

@mourner
Copy link
Member

mourner commented Jun 30, 2015

@Eschon yeah, I probably didn't notice this because on Retina screen, it's even less visible.

@Eschon
Copy link
Contributor Author

Eschon commented Jul 30, 2015

This seems to affect Firefox now too in some cases.
I couldn't reproduce it in jsFiddle but if you look at that site
I get the same spaces in Firefox 39 and 41.0a2

Edit: This seems to be a problem with iframes. If I open the map directly it doesn't reproduce.

@IvanSanchez
Copy link
Member

I doubt this will be possible for 1.0 without a lot of hacking. Pushing to the bottom of the backlog.

@afilp
Copy link

afilp commented Oct 13, 2015

We experience the same problem on latest Chrome too. I wish that you find a possible fix as OpenStreet maps do not show well with these lines. Thanks.

@cmulders
Copy link
Contributor

Especially on darker maps or images (in my case) the issue is quite noticeable. I think that antialiasing in the browser causes the spaces between tiles due to the fractional transform during zooming, as mentioned by Ivan.

Until a better solution is available, I will use this workaround (or hack) to make the tiles 1 pixel larger, with the side effect that they overlap by 1 px. Besides that the tiles will be slightly enlarged and scaled (by 1px).

/* 
 * Workaround for 1px lines appearing in some browsers due to fractional transforms
 * and resulting anti-aliasing.
 * https://github.com/Leaflet/Leaflet/issues/3575
 */
(function(){
    var originalInitTile = L.GridLayer.prototype._initTile
    L.GridLayer.include({
        _initTile: function (tile) {
            originalInitTile.call(this, tile);

            var tileSize = this.getTileSize();

            tile.style.width = tileSize.x + 1 + 'px';
            tile.style.height = tileSize.y + 1 + 'px';
        }
    });
})()

@Eschon
Copy link
Contributor Author

Eschon commented Oct 23, 2015

@cmulders Thanks for the workaround!
Since we mainly have maps of ski resorts that are mostly white and blue. We ignored the spaces for now, with your workaround it looks a lot better.

@hyperknot
Copy link
Collaborator

Made a jsbin with cartodb dark tiles, the lines are visible even on retina screen:
http://jsbin.com/ratoli/5/edit?html,js,output

Safari / Chrome buggy, FF OK for me.

@hyperknot
Copy link
Collaborator

We should make a Leaflet-less Chrome bug report for this, so it's fixed in future Chrome versions.

@Eschon
Copy link
Contributor Author

Eschon commented Jan 25, 2016

@hyperknot I think there is already a Chrome bug report, but I can't find it right now.

@mehany
Copy link

mehany commented Feb 3, 2016

I am using leafletjs 1.0 beta and I am seeing this bug as well sometimes on ( latest: chrome , safari, firefox ) on osx El Capitan. when I edit an images's transform css property by 1px, the edited tile aligns with the tile next to it.

// ex.
 transform: translate3d(1556px, -81px, 0px);
 // to
 transform: translate3d(1555px, -80px, 0px);

Sometimes this bug does not appear though ( that 1px of difference ) !! not sure why :( but I am currently guessing it has to do with the styling of the map container.

Edit: Say the tiles align correctly on render and does not show any 1px of difference, a gap will visible on map move event. The behavior is like a flash of a 1px border around the tile.

@href
Copy link

href commented Mar 31, 2016

I found a css workaround that gets rid of the problem for me on Safari 9.1 on OS X El Capitan:

.leaflet-tile-container img {
    box-shadow: 0 0 1px rgba(0, 0, 0, 0.05);
}

I can't take much credit however, I took it from the following Stackoverflow answer which also hints at why this helps: http://stackoverflow.com/a/17822836/138103

Using box-shadow solves the problem more directly: it extends the repaint dimensions of the box, forcing WebKit to repaint the extra pixels. The known performance implications of box-shadow in mobile browsers are directly related to the blur radius used, so a one pixel shadow should have little-to-no effect.

Maybe this can be used as a proper fix, though it would probably be good if others tried this first. It works for me however and doesn't seem to lead to any problems in other browsers.

@IvanSanchez
Copy link
Member

@href Maybe you could make a pull request with that fix? That'd make it easier to test.

@hyperknot
Copy link
Collaborator

@href @IvanSanchez Are you sure that this won't affect rendering performance? I think we should profile how does adding a box-shadow with an alpha opacity affect mobile devices for example, it might have a visible effect on performance, or even possibly disable hardware acceleration.

href pushed a commit to href/Leaflet that referenced this issue Mar 31, 2016
@href
Copy link

href commented Mar 31, 2016

@IvanSanchez done.

Are you sure that this won't affect rendering performance? I think we should profile how does adding a box-shadow with an alpha opacity affect mobile devices for example, it might have a visible effect on performance, or even possibly disabling hardware acceleration for panning.

I'm not at all sure what the effect of this is. From the Stackoverflow answer this doesn't seem to have an effect, but that's just trusting someone else's opinion on a tangentially related issue. It would surely be a great idea if someone more knowledgable could look into it and profile my workaround.

I just got lucky when I googled around and I wanted others to know.

@IvanSanchez
Copy link
Member

@hyperknot @href I'll happily perform some benchmarks in a couple of weeks against my set of test browsers.

@hyperknot
Copy link
Collaborator

@IvanSanchez @href Also, it might be good to limit this hack to affected browsers only, not just apply it globally.

@IvanSanchez is there a recommended workflow for profiling Leaflet rendering performance?

@href
Copy link

href commented Mar 31, 2016

Also, it might be good to limit this hack to affected browsers only, not just apply it globally.

I personally only see it in Safari, so it would make sense to limit it for safari. There were mentions of people seeing this in Chrome however. Does anyone still see this bug in other webkit browsers?

@IvanSanchez
Copy link
Member

It's quite trivial to add a CSS class to the map only for selected browsers, in the L.Map constructor stuff.

@href The issue is present in my Chromium 49

@hyperknot I'm not aware of the best way to profile these kind of things. Let's talk about that this weekend ;-)

@eugenelet
Copy link

Is there any update on how to mitigate this issue, any workaround perhaps? I still can't get rid of the white grids.

@Eschon
Copy link
Contributor Author

Eschon commented Dec 28, 2022

@eugenelet @Malvoz edited my initial post to include a list of many different workarounds.
The one I personally use is this one: #3575 (comment)

@eugenelet
Copy link

@Eschon Thanks for the workaround. I tried to solve it using CSS:

.leaflet-tile-container img {
  width: 256.5px !important;
  height: 256.5px !important;
}

Not sure if achieves the same thing.

@woheller69
Copy link

for me it works if I increase to 257 in CSS. 256.5px is not sufficient

.leaflet-tile-container img {
  width: 257px !important;
  height: 257px !important;
}

@lapo-luchini
Copy link

The new CSS approach mix-blend-mode: plus-lighter suggested in the Chrome issue seems like the ideal solution to me.
(increasing pixel size of tiles leads to deformations I don't really find acceptable)

@IvanSanchez
Copy link
Member

@lapo-luchini This looks like a promising clean approach, but I cannot get it to work on Chromium 110.0.5481.177 on Linux. Could you please elaborate a bit about how you made that work? Would that CSS rule apply to the tiles themselves, or to the tile pane?

@lapo-luchini
Copy link

I did this:

img.leaflet-tile {
    /* work-around from here: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
    mix-blend-mode: plus-lighter;
}

Actually, the custom CSS rules I'm using is this one, the first part was already there for a while:

img.leaflet-tile, img.leaflet-marker-icon, img.leaflet-marker-shadow {
    /* work-around from here: https://github.com/Leaflet/Leaflet/issues/161 */
    outline: 1px solid transparent;
    /* work-around from here: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
    mix-blend-mode: plus-lighter;
}

@indigoxela
Copy link

Cool, seems like it even works without the additional outline, only with mix-blend-mode. Just tested with Chrome version 111.0.5563.64 on Linux. 👍

http://olga.indigofloat.at/bugdemo/demo-chrome-7.html

@IvanSanchez
Copy link
Member

I'm testing that at https://plnkr.co/edit/QdXlRWUrGBLCxeXy , and still can see the gaps.

image

It does help when the page zoom is at 100%, which is a good thing. But this bug displays on two scenarios: fractional zoom and page zoom; this means that the fix only covers one of those.

@indigoxela
Copy link

... this bug displays on two scenarios: fractional zoom and page zoom; this means that the fix only covers one of those.

@IvanSanchez that's right, with the browser window zoomed, the gaps are still there. But with window zoom 100% everything's fine - without the visual glitch (slight "wobbling") of the tile size hack. So, I'd say it's a good step forward.

@jonkoops jonkoops unpinned this issue Jul 14, 2023
mcauer added a commit to GIScience/ohsome-dashboard that referenced this issue Aug 23, 2023
should fix tile edge rendering artefacts
see:  Leaflet/Leaflet#3575
@terax6669
Copy link

terax6669 commented Sep 16, 2023

I noticed today that the issue seems to be partially gone on both Chrome and Chromium (116).
Once all tiles are loaded the seams disappear (you can see them when tiles are loading, but it looks much better than a few years ago)

Edit: nevermind, npm must've auto updated the leaflet package and I didn't even notice, it has the plus-lighter fix applied.

@HolgerJeromin
Copy link

HolgerJeromin commented Sep 18, 2023

Which on the other hand is a proof that this issue should be closed as fixed! :)

@IamMusavaRibica
Copy link

I'm still getting this issue on Chrome build 116.0.5845.188
The following workaround can be used, however no more smooth zooming in and out (similarly to how the maps work when you disable hardware acceleration in the browser)

<script>L_DISABLE_3D = true;</script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="..." crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="..." crossorigin=""</script>

@GGlanfield
Copy link

Just upgraded from 1.9.3 to 1.9.4 and these gaps now appear (in a non repeatable way) as I zoom in/out and pan the map.
image
If I revert to 1.9.3, it's fine. Using Win 11 + Chrome 117 (zoom at 100%).

@alexandrechabs
Copy link

I have same with 1.9.4 and chrome 117 but not in firefox 118 anyone had a solution ?

@grundmanise
Copy link

grundmanise commented Jan 5, 2024

That's quite strange, but to fix this issue in Chrome Version 120.0.6099.129 (Official Build) (arm64) I had to revert the fix added by default:

.leaflet-container img.leaflet-tile {
	/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
	mix-blend-mode: plus-lighter;
}

Leaflet v1.9.4.

@IamMusavaRibica
Copy link

That's quite strange, but to fix this issue in Chrome Version 120.0.6099.129 (Official Build) (arm64) I had to revert the fix added by default:

.leaflet-container img.leaflet-tile {
	/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
	mix-blend-mode: plus-lighter;
}

Leaflet v1.9.4.

That's correct. When I was trying out various css things from leaflet, found this one to be causing the white lines. Setting to 'normal' or completely disabling this css rule within devtools fixes white lines.

@ribes4
Copy link

ribes4 commented Mar 1, 2024

That's quite strange, but to fix this issue in Chrome Version 120.0.6099.129 (Official Build) (arm64) I had to revert the fix added by default:

.leaflet-container img.leaflet-tile {
	/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
	mix-blend-mode: plus-lighter;
}

Leaflet v1.9.4.

I was using Leaflet 1.9.2 and never had this issue, I just upgraded to Leaflet 1.9.4 and it appeared. The white lines no longer appear by removing those lines from the css.

My current Chrome Version is 122.0.6261.94 (Official Build) (64-bit)

@staterconsulting
Copy link

staterconsulting commented Mar 17, 2024

Well I am confused - I upgraded to 1.9.4 and I see the lines. If I set mix-blend-mode: plus-lighter !important at the tile level it removes it.

Chrome Version 122.0.6261.129 (Official Build) (64-bit)

@frantortosa
Copy link

frantortosa commented Jul 2, 2024

Just in case someone has my issue (with Leaflet 1.9.4 and Mapbox tiles), which is slightly different, in my case the lines appear only occasionally between some tiles at some zoom levels (not in the whole map but only in some different random areas each time, and also not visible in MAC retina screens, but visible in windows, even 4K monitors).

The mix-blend-mode: plus-lighter solution did not do the job but

.leaflet-container img.leaflet-tile {
  mix-blend-mode: normal;
}

Worked better for me (at least in Chrome). Also mix-blend-mode: hue; has an acceptable result.

Still I can see some subtle blue line over the ground area sometimes.

Combined with the size increase it is finally perfect:

.leaflet-container img.leaflet-tile {
  mix-blend-mode: normal;
  width: 513px !important;
  height: 513px !important;
}

EDIT again:

I realised that RETINA screens (e.g. Mac laptops) have a different behaviour than non RETINA: this is the final implementation:

.leaflet-container img.leaflet-tile {
  mix-blend-mode: normal !important;
  @media (-webkit-min-device-pixel-ratio: 1) {
    // NON RETINA
    width: 513px !important;
    height: 513px !important;
  }
  @media (-webkit-min-device-pixel-ratio: 2) {
    // RETINA
    width: 512px !important;
    height: 512px !important;
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment