ionic-team / ionicons

Premium hand-crafted icons built by Ionic, for Ionic apps and web apps everywhere 🌎
http://ionicons.com
MIT License
17.4k stars 2.06k forks source link

bug: some icons appear jagged in safari/webkit browsers #1176

Closed danieletulone closed 2 months ago

danieletulone commented 1 year ago

Current Behavior

image

Expected Behavior

To not have rendering issues.

Steps to Reproduce

Code Reproduction URL

No response

Additional Information

No response

liamdebeasi commented 1 year ago

Thanks for the report. What version of iOS are you testing this on?

danieletulone commented 1 year ago

I have tested on two iphone devices:

liamdebeasi commented 1 year ago

Thanks for the additional information. Could you please clarify what the issue is with the rendering of the icons?

danieletulone commented 1 year ago

Of course! As you can see the icons have some gliches. image

xnousnow commented 1 year ago

Does that occur on any other icons? +edit: I'm using iPhone SE2 and the glitch is also on mine. It does that to 'accessibility', 'airplane', 'alarm', 'aperture' and many other icons, some icons don't have glitches. you can see more impact with filled icons.

hacketiwack commented 1 year ago

Same on my Dell screen with Safari 16.3

Icon Badly Rendered

liamdebeasi commented 1 year ago

Thanks everyone! I can reproduce this on my end.

lincolnthree commented 1 year ago

Also affected by this. What I found odd is that if I disable the stroke style:

image

Some of the icons seems to round themselves out and the jagged edges go away, particularly book, but it doesn't work with other icons.

hacketiwack commented 1 year ago

@lincolnthree your trick works for me on all the icons I tested: search and language. For those icons, I set the stroke attribute to inherit. However, it doesn't work, for example, for the icon menu.

matfantinel commented 1 year ago

I am also facing this on an Ionic app, when running on iOS.

I did run some experiments and it seems to get fixed, at least sometimes, when adding -webkit-transform: translate3d(0,0,0) to the icons. From what I understood, this line of CSS makes some devices enable hardware acceleration on that element, which might result in a better rendering.

In my ionic-angular app, I added to the global.scss file:

ion-icon {
  -webkit-transform: translate3d(0,0,0);
}

I styled the ion-icon element itself instead of the svg directly because I can't access it because of the Shadow DOM.

Edit: it seems to work on the Ionicons site and the ion-icon docs on the Ionic site, but it didn't in my app. Hopefully a solution is found soon. Safari is notoriously bad at rendering SVGs as it seems. For the record FontAwesome (font version, not SVG) works fine, so maybe a font version of Ionicons would work? Is such a thing even available?

fer0n commented 11 months ago

For those icons, I set the stroke attribute to inherit. However, it doesn't work, for example, for the icon menu.

How were you able to do this? That stroke is set directly on the svg element of the IonIcon, which is using a shadow dom and there aren't any shadow parts exposed. Am I missing something?

matfantinel commented 11 months ago

@fer0n I think that's only possible if you use the SVGs directly instead of the IonIcon component. Might be worth a shot, if only to see if that fix actually works for you. Then the options would either be to use the SVGs directly whenever the icons have this issue or fork Ionicons and expose the shadow part.

Hopefully either Safari gets its $#1T together or the Ionic team figures out a better fix for this soon

fer0n commented 11 months ago

Thanks! I ended up wrapping the IonIcon in a component that removes the stroke from the icon. Not ideal, but I don't see any good solutions.

import { IonIcon } from "@ionic/react";
import React, { useMemo } from "react";

interface IonIconProps {
  color?: string;
  flipRtl?: boolean;
  icon?: string;
  ios?: string;
  lazy?: boolean;
  md?: string;
  mode?: "ios" | "md";
  name?: string;
  size?: string;
  src?: string;
}

/**
 * **Do not use if icon needs a stroke!** Fixes jagged icon appearance on iOS for filled icons.
 */
export default function IonIconNoStroke({ icon, ...props }: IonIconProps) {
  const iconWithoutStrokeStyle = useMemo(() => {
    if (icon) {
      return removeStrokeStyleFromIcon(icon);
    }
  }, [icon]);

  return <IonIcon icon={iconWithoutStrokeStyle ?? icon} {...props} />;
}

function removeStrokeStyleFromIcon(icon: string) {
  const tempElement = document.createElement("div");
  tempElement.innerHTML = icon;
  const cleanedElement = tempElement.querySelector("svg");
  if (cleanedElement) {
    cleanedElement.style["stroke"] = "unset";
    return tempElement.innerHTML;
  }
}
aeharding commented 11 months ago

Unfortunately, this fix is much more hacky for projects using Ionic then if it were patched in Ionic directly.

@liamdebeasi would it be possible to either add stroke: unset to Ionic Icons package, or alternatively add slot so we can fix this with a CSS selector?

Thanks!!

liamdebeasi commented 10 months ago

Hi everyone,

While we wait for the WebKit team to address this, I have been experimenting with some potential workarounds. Can someone try this ionicons dev build, and let me know if it makes the issue better/worse? This patch adds transform: translate3d(0, 0, 0) to the svg. It's possible this may come with some negative performance side effects.

npm install ionicons@7.1.3-dev.11689001487.15dc2e02
fer0n commented 10 months ago

@liamdebeasi looks like that's the same solution that @matfantinel mentioned above, or are you proposing something else?

If it's the same, that fixed the issue for them (and same for me) only on desktop safari, the issue remains on iOS.

liamdebeasi commented 10 months ago

It's the same solution as https://github.com/ionic-team/ionicons/issues/1176#issuecomment-1572685263, but the solution is applied to the svg inside of ion-icon, so it should work when using the ion-icon component too. The solution provided in the linked comment only worked when you were working with the SVG directly.

matfantinel commented 10 months ago

@liamdebeasi unfortunately it still has the same issue after installing that version of the package. Fixes on desktop Safari, but still looks choppy on iOS (I tested as an installed app with Capacitor)

liamdebeasi commented 10 months ago

Thanks for testing. Do you have a screenshot of the issue happening on iOS? I was able to reproduce some jaggedness all the way back to iOS 14, so it's possible there are multiple SVG rendering bugs at play.

matfantinel commented 10 months ago

@liamdebeasi here it is! It's really similar to the one earlier in this thread. This screenshot was after applying the tentative fix, but it looked identical before.

IMG_2645

aeharding commented 10 months ago

Attaching for reference:

https://bugs.webkit.org/show_bug.cgi?id=258375

Beelink commented 8 months ago

Unfortunately, this fix is much more hacky for projects using Ionic then if it were patched in Ionic directly.

@liamdebeasi would it be possible to either add stroke: unset to Ionic Icons package, or alternatively add slot so we can fix this with a CSS selector?

Thanks!!

I think adding a slot is a perfect solution!

Any updates on this?

aeharding commented 2 months ago

This appears to be resolved in iOS 17.4

liamdebeasi commented 2 months ago

Checked on my end, and this issue does appear to be resolved in iOS 17.4.