quick-lint-js icon indicating copy to clipboard operation
quick-lint-js copied to clipboard

12$: website: svg icons render incorrectly on Chrome/Edge/Safari

Open strager opened this issue 2 years ago • 5 comments

strager avatar Aug 10 '22 05:08 strager

Worked around in commit 2437f62faca2614b0d80c5c6af1bcb1366a82820.

strager avatar Aug 10 '22 09:08 strager

Commit d6dd3d5ebbf66b40fa091157e4c5655093a88afc enabled spritesheeting for certain SVGs. Broken SVGs are marked with disableSpritesheet: false in website/public/index.mjs.

strager avatar Aug 15 '22 09:08 strager

I suspect there's a bug in either browsers or in svg-sprite (the library we use).

strager avatar Aug 15 '22 09:08 strager

This patch sorta works. Some sprites bleed though. Screen Shot 2022-09-06 at 1 51 20 AM

diff --git website/public/index.mjs website/public/index.mjs
index ab50f1c5..2d489769 100644
--- website/public/index.mjs
+++ website/public/index.mjs
@@ -127,11 +127,11 @@ for (let [iconName, icon] of Object.entries(icons)) {
     // HACK(#818): Some SVGs are broken in Chrome and Safari when spritesheeted.
     // This might be a bug in the svg-sprite library. Remove these offending
     // SVGs from the spritesheet as a workaround.
-    if (!icon.disableSpritesheet) {
+    //@@@ if (!icon.disableSpritesheet) {
       spriteSheetItem = iconsSpriteSheet.addSVG(
         path.join(__dirname, icon.path)
       );
-    }
+    //@@@ }
   }
   icon.spriteSheetItem = spriteSheetItem;
 }
diff --git website/src/sprite-sheet.mjs website/src/sprite-sheet.mjs
index 4f75509e..28239a78 100644
--- website/src/sprite-sheet.mjs
+++ website/src/sprite-sheet.mjs
@@ -38,7 +38,7 @@ export class ExternalSpriteSheet {
         },
       },
       mode: {
-        defs: true,
+        view: true,
       },
     };
     let spriter = new SVGSpriter(config);
@@ -51,7 +51,8 @@ export class ExternalSpriteSheet {
       );
     }
     let { result } = await spriter.compileAsync();
-    return result.defs.sprite.contents.toString();
+    console.log(result);
+    return result.view.sprite.contents.toString();
   }
 }
 
@@ -84,11 +85,9 @@ class ExternalSpriteSheetImage {
   }
 
   makeReferenceHTML({ attributes, externalFileURI }) {
-    return makeSVGSymbolReference({
-      attributes,
-      externalFileURI,
-      symbolID: this._symbolID,
-    });
+    return `<img src="${externalFileURI}#${this._symbolID}" ${makeAttributesHTML(
+      attributes
+    )}>`;
   }
 }

strager avatar Sep 06 '22 08:09 strager

The # method causes the browser to issue one request per img. So this is a bad solution.

strager avatar Sep 07 '22 02:09 strager

👀

erlliam avatar Sep 23 '22 02:09 erlliam

@erlliam Did you manage to make a reduced test case demonstrating the problem?

strager avatar Jan 31 '23 09:01 strager

I have not. I have removed my assignment.

erlliam avatar Feb 15 '23 02:02 erlliam

This is still an issue as of commit 763fd5455de4fbd8aefb32ddaadd7f7e71b94a3c.

strager avatar Mar 08 '23 03:03 strager

It looks like this issue might be caused by this bug: https://bugs.chromium.org/p/chromium/issues/detail?id=109212

I tested some of the svgs from this repo and svgs that use style="fill:url(#linearGradientId)" are not rendering correctly in Chrome if they included in the HTML with a <use> tag that references an external svg file. The same svg can be pasted inline in the html (without <use>) and it renders correctly.

examples

  • https://mattcodes01.github.io/svg-chrome-bug/ (everything renders correctly in Firefox but in Chrome only the inline svg and the svg that doesn't use fill:url works)

these are the svgs from the website that are using fill:url

  • https://mattcodes01.github.io/svg-chrome-bug/with-url.html (renders correctly in Firefox)
  • https://mattcodes01.github.io/svg-chrome-bug/without-url.html (fill:url code removed from sprite-sheet, render the same in Chrome and Firefox)

these svgs also use fill:url but are not visible in Chrome because they are made up of all/mostly linear gradient fills using the fill:url

  • https://mattcodes01.github.io/svg-chrome-bug/not-visible.html (you can see a single diagonal line in Chrome for the part of the Neovim logo that doesn't use fill:url)
  • https://mattcodes01.github.io/svg-chrome-bug/not-visible-without-url.html (fill:url code removed from sprite-sheet, render the same in Chrome and Firefox)

mattcodes01 avatar Jun 17 '23 00:06 mattcodes01

@mattcodes01 Thanks for investigating! I appreciate it. I updated the inline comment with more info here: ffba4e73e6a9149a22959cf2ee55f427ecbe77b6

// HACK(#818): Some SVGs are broken in Chrome and Safari when spritesheeted.
// This appears to be a bug in both WebKit and Chromium:
// https://bugs.webkit.org/show_bug.cgi?id=65344
// https://bugs.chromium.org/p/chromium/issues/detail?id=109212
//
// Remove these offending SVGs from the spritesheet as a workaround.

strager avatar Jun 22 '23 20:06 strager