Florian Monfort
Florian Monfort

Reputation: 313

SVGs with linear gradient not handled by Cordova - iOS

We are implementing icons in our Ionic / Cordova app that uses SVG icons and whenever exported from Adobe XD, and implemented in the iOS version of the app, the gradient part of the icon shows correctly on Web (Chromium based browsers like Edge / Chrome) and Android but not on iOS.

This is how the icon looks normally in Chrome/Edge/Android and in XD:

icon that looks normal

And this what the icon looks like once in Cordova - iOS:

enter image description here

As you can see, the dot on the icon that has normally a gradient appears black. We cannot figure out why.

Here is the code of the SVG that Adobe XD produces:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><defs><style>.a{fill:#fff;opacity:0;}.b{fill:none;stroke:#5d5d5d;stroke-linecap:round;stroke-width:1.5px;}.b,.c{stroke-miterlimit:10;}.c{stroke:#fff;fill:url(#a);}</style><linearGradient id="a" y1="0.5" x2="1" y2="0.5" gradientUnits="objectBoundingBox"><stop offset="0" stop-color="#d9315d"/><stop offset="1" stop-color="#dc2224"/></linearGradient></defs><g transform="translate(0 0)"><rect class="a" width="24" height="24"/><g transform="translate(-1047.065 -371.769)"><path class="b" d="M1057.747,389.029v-4.016a3.157,3.157,0,0,0-.211-1.137l-.07-.183a2.228,2.228,0,0,0-.4-.662l-.8-.921-.566-.653-4.345-5.017a.224.224,0,0,1,.169-.37h18.052a.223.223,0,0,1,.169.37l-4.923,5.685-.658.76a3.359,3.359,0,0,0-.552.883h0a3.179,3.179,0,0,0-.253,1.243v9.081a.224.224,0,0,1-.355.182l-2.889-2.074" transform="translate(-1.701 -1.801)"/><circle class="c" cx="4.593" cy="4.593" r="4.593" transform="translate(1047.565 372.269)"/></g></g></svg>

Because we thought maybe Adobe XD produces some non compliant code of some sort, we decided to just put it through some SVG sanitizer like this one: http://svg.enshrined.co.uk/ , producing the following code:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24">
  <defs>
    <style>.a{fill:#fff;opacity:0;}.b{fill:none;stroke:#5d5d5d;stroke-linecap:round;stroke-width:1.5px;}.b,.c{stroke-miterlimit:10;}.c{stroke:#fff;fill:url(#a);}</style>
    <linearGradient id="a" y1="0.5" x2="1" y2="0.5" gradientUnits="objectBoundingBox">
      <stop offset="0" stop-color="#d9315d"></stop>
      <stop offset="1" stop-color="#dc2224"></stop>
    </linearGradient>
  </defs>
  <g transform="translate(0 0)">
    <rect class="a" width="24" height="24"></rect>
    <g transform="translate(-1047.065 -371.769)">
      <path class="b" d="M1057.747,389.029v-4.016a3.157,3.157,0,0,0-.211-1.137l-.07-.183a2.228,2.228,0,0,0-.4-.662l-.8-.921-.566-.653-4.345-5.017a.224.224,0,0,1,.169-.37h18.052a.223.223,0,0,1,.169.37l-4.923,5.685-.658.76a3.359,3.359,0,0,0-.552.883h0a3.179,3.179,0,0,0-.253,1.243v9.081a.224.224,0,0,1-.355.182l-2.889-2.074" transform="translate(-1.701 -1.801)"></path>
      <circle class="c" cx="4.593" cy="4.593" r="4.593" transform="translate(1047.565 372.269)"></circle>
    </g>
  </g>
</svg>

Which at first look does some cleaner, but still does not fix our issue.

Most of the icons we use have this gradient in some form or another. And we have other examples of these icons unable to use the gradient in Cordova - iOS version.

Upvotes: 2

Views: 456

Answers (1)

Sergey Rudenko
Sergey Rudenko

Reputation: 9227

So rendering SVG likely has less to do with Cordova, but with specific browser ability to handle SVG.

In your case it seems like you apply "gradient" using url(...) reference within css.

Safari introduced a requirement for the url in this case to feature "absolute" path.

Try the same icon but change the way you refer url from:

fill:url(#a)

to:

fill:url(https://yourwebsite.com/yourpage/#a)

Basically you need something like this for Safari:

fill: url( {{ location.href }}#filterOrGradientId )

It is a pain to work around this issue. So one suggestion could be also to try referring the gradient using fill attribute on the svg circle element.

Example from MDN:

<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <linearGradient id="myGradient" gradientTransform="rotate(90)">
      <stop offset="5%"  stop-color="gold" />
      <stop offset="95%" stop-color="red" />
    </linearGradient>
  </defs>

  <!-- using my linear gradient -->
  <circle cx="5" cy="5" r="4" fill="url('#myGradient')" />
</svg>

Upvotes: 1

Related Questions