1

I'm attempting to create a grid overlay using an absolutely positioned uninteractable div. I'm attempting to accomplish this using a repeating-linear-gradient attribute as I've seen suggested elsewhere for this solution. The implementation of this feature works fine on Chrome, but I seem to need some sort of polyfill -- or I'm doing something wrong -- for firefox compatibility.

To view the issue, in the most recent version of firefox (52, although other versions exhibit my issue as well) and access this jsfiddle:

https://jsfiddle.net/g5v0o7ks/4/

the resultant css in question:

background-size: 256px 256px;
background-image: 
    repeating-linear-gradient(to right, transparent, transparent calc(100% - 1px), black calc(100% - 1px), black 100%), 
    repeating-linear-gradient(to bottom, transparent, transparent calc(100% - 1px), black calc(100% - 1px), black 100%);

increment each of the inputs by 1 each. Decrement them too. The linear gradients entirely vanish when exceeding 255 pixels, which doesn't seem to happen in chrome. I've tried handling this with percentage values as well, but the gradients still vanish over the hard 255 pixel limit.

I assume that this issue isn't an intended behavior, as background-size doesn't have any noted pixel limit on the MDN page. Has anyone run into this issue before, or do you notice an error in my code that's causing the jsfiddle not to function as expected?

John Kulp
  • 123
  • 1
  • 12
  • I have no idea what you're doing there, but I can assure you it's not working past 255px on either direction in Chrome (Version 58.0.3029.81 (64-bit)) on a linux machine either. – tao May 03 '17 at 21:23
  • That's odd! It works fine past 255px on Chrome 57.0.2987.133 (64 bit) on mac. Also, the purpose of this is to overlay a deep zoom image without having the overlay move along with the image. So I want this to be set dynamically with 2, 4, 8, or potentially 16 columns evenly splitting the page by updating the background size with "(image width / #cols)px (image height / #cols)px". – John Kulp May 03 '17 at 21:29

1 Answers1

1

Your issue is happening in Chrome (v.58 - 64-bit), on a Linux machine, too. The workaround is to modify your background-image from:

 background-image: repeating-linear-gradient(to right, transparent, transparent calc(100% - 1px), black calc(100% - 1px), black 100%),   repeating-linear-gradient(to bottom, transparent, transparent calc(100% - 1px), black calc(100% - 1px), black 100%)

... to (all 1px instances replaced by 2px):

 background-image: repeating-linear-gradient(to right, transparent, transparent calc(100% - 2px), black calc(100% - 2px), black 100%),   repeating-linear-gradient(to bottom, transparent, transparent calc(100% - 2px), black calc(100% - 2px), black 100%)

...when between 256px and 511px. Haven't tested, but I assume ... - 3px... is going to work up to 767px.

Do you see a pattern here? As you'd expect, this works in Firefox too.

Why? Beats me! But I recon it has something to do with sub-pixel rendering. I know, it shouldn't (after all, you're deducting 1px) but this is why web is grand, isn't it?

tao
  • 82,996
  • 16
  • 114
  • 150
  • It looks like it'll take some fiddling to get that aligned with a final 1px thick grid, but thanks! Do you know any way to detect whether this issue will arise? Because increasing the thickness of the resulting lines will make it look normal on the browsers with the issue, but ugly on the ones that didn't have the issue in the first place. – John Kulp May 03 '17 at 21:37
  • As stated in the question, I have no idea why this happens. Let's hope you get an answer from someone with more intimate knowledge on render engines and how repeating linear gradients are computed, giving us both a why and a how (to detect it). I've already fav-ed your question so I'll get updated on any new answers. Congrats for the question and happy coding! – tao May 03 '17 at 21:41
  • @JohnKulp, on a different note, I think a much more reliable way to get the result you're after is using an absolutely positioned `` and just draw the grid behind the viewport in it. That's how I'd do it, but I admit I'm biased from having worked heavily with `d3.js` lately on a few projects. I'm still in awe as to what can be achieved and how easy it is after you get past the moderately steep learning curve. It's cross-browser and just a few lines of code. – tao May 03 '17 at 21:46
  • Thanks for the advice! The product I'm working on is already very SVG heavy, outlining objects detected through image analysis with SVG polygons, so I want to avoid putting to much pressure on that facet of the rendering engine. I'm thinking that I'll just drop an absolutely positioned table element over top, add in a bunch of cells, and then alter the css to determine how many columns/rows are shown to fit the container. – John Kulp May 03 '17 at 21:52
  • 1
    Now, ***that*** would be ugly, @John, any way you look at it. As a friend of mine would put it: *So 80's!!!*. Look at what WebGL is capable of in today's browsers and stop worrying about them not being able to render intensive `` pages. As a matter of fact, ``s are lighter than most DOM elements, unless you're using graphical filters, (blur, color - which are still lighter on ``s than on images). It's why every browser game uses them. And, as a last argument, ~10 straight ``s are nothing, really. An `80px x 80px` is larger than that. – tao May 03 '17 at 22:02
  • Thanks for getting back to me about that! I'll go ahead and write an SVG implantation. Anyway, I'll mark your response as having answered me after a few days to give a chance for anyone who better understands the initial issue I had to come out of the woodwork. – John Kulp May 04 '17 at 14:40