x00
x00

Reputation: 13843

In Safari svg mask looks blurry like if it's raster

In Safari but not in Chrome applying svg mask on svg icon renders blurry edges. I've created minimal reproducible example... at least I hope that it's reproducible. Because this effect is not constant:

I've tried it on desktop in 15.6.1 and 16.4 and in webviews on an assortment of Apple mobile devices.

The actual result:

enter image description here

The expected result:

enter image description here

<html>
<head>
    <style>
    .logo {
        width: 96px;
        height: 96px;
        -webkit-mask-size: contain;
        mask-size: contain;
        -webkit-mask-image:
            url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PG1hc2sgaWQ9ImEiIHN0eWxlPSJtYXNrLXR5cGU6YWxwaGEiIG1hc2tVbml0cz0idXNlclNwYWNlT25Vc2UiIHg9IjAiIHk9IjAiIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCI+PHBhdGggZD0iTTQ4IDI0YzAgMTkuMjA1LTQuNzk1IDI0LTI0IDI0UzAgNDMuMjA1IDAgMjQgNC43OTUgMCAyNCAwczI0IDQuNzk1IDI0IDI0eiIgZmlsbD0iI2ZmZiIvPjwvbWFzaz48ZyBtYXNrPSJ1cmwoI2EpIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMCAwaDQ4djQ4SDB6Ii8+PC9nPjwvc3ZnPg==);
        mask-image:
            url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PG1hc2sgaWQ9ImEiIHN0eWxlPSJtYXNrLXR5cGU6YWxwaGEiIG1hc2tVbml0cz0idXNlclNwYWNlT25Vc2UiIHg9IjAiIHk9IjAiIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCI+PHBhdGggZD0iTTQ4IDI0YzAgMTkuMjA1LTQuNzk1IDI0LTI0IDI0UzAgNDMuMjA1IDAgMjQgNC43OTUgMCAyNCAwczI0IDQuNzk1IDI0IDI0eiIgZmlsbD0iI2ZmZiIvPjwvbWFzaz48ZyBtYXNrPSJ1cmwoI2EpIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMCAwaDQ4djQ4SDB6Ii8+PC9nPjwvc3ZnPg==);
        background-image:
            url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTAgMGgyMHYyMEgweiIvPjwvc3ZnPg==);
            background-size: cover;
    }
    </style>
</head>
<body>
    <div class="logo"/>
</body>
</html>

SVGs

  1. The mask:
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_16513_8424" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="48" height="48">
<path d="M48 24C48 43.2052 43.2052 48 24 48C4.79475 48 0 43.2052 0 24C0 4.79475 4.79475 0 24 0C43.2052 0 48 4.79475 48 24Z" fill="white"/>
</mask>
<g mask="url(#mask0_16513_8424)">
<rect width="48" height="48" fill="black"/>
</g>
<defs>
</defs>
</svg>
  1. The icon:
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="20" height="20" fill="#000000"/>
</svg>

Upvotes: 4

Views: 9022

Answers (3)

user26567953
user26567953

Reputation: 11

I also had this problem while working with safari browsers and iPhones. I tried the methods mentioned above but they didn't worked in my case. But when I check my SVG images I found one filter in SVG image as

<g filter="url(#filter3_bd_350_4485)"> some element </g>

When I removed the filter tag, the SVG images were working great in both safari and iPhones. It may not be an actual solution, but it may work in some cases. Hence try removing this filter.

Upvotes: 1

herrstrietzel
herrstrietzel

Reputation: 17316

Apparently, safari has problems with mask-images containing masked elements.

Fortunately you can simplify your mask:

.logo {
  width: 96px;
  height: 96px;
  background: #000;
  display: inline-block;
  mask-size: contain;
  -webkit-mask-size: contain;
  -webkit-mask-image:url("data:image/svg+xml,%3Csvg width='48' height='48' fill='none' viewBox='0 0 48 48' xmlns='http://www.w3.org/2000/svg'%3E%3Cmask id='a' style='mask-type:alpha' maskUnits='userSpaceOnUse' x='0' y='0' width='48' height='48'%3E%3Cpath d='M48 24c0 19.205-4.795 24-24 24S0 43.205 0 24 4.795 0 24 0s24 4.795 24 24z' fill='%23fff'/%3E%3C/mask%3E%3Cg mask='url(%23a)'%3E%3Cpath fill='%23000' d='M0 0h48v48H0z'/%3E%3C/g%3E%3C/svg%3E");
}

.logo2 {
  width: 96px;
  height: 96px;
  background: #000;
  display: inline-block;
  mask-size: contain;
  -webkit-mask-size: contain;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'%3E%3Cpath d='M48 24c0 19.205-4.795 24-24 24S0 43.205 0 24 4.795 0 24 0s24 4.795 24 24z' fill='%23000' /%3E%3C/svg%3E");
     
}
<p>Original</p>
<div class="logo"></div>
<p>Fixed</p>
<div class="logo2"></div>

Your mask svg can be reduced to the mask shape itself:

<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
  <path d="M48 24c0 19.205-4.795 24-24 24S0 43.205 0 24 4.795 0 24 0s24 4.795 24 24z" fill="#000" />
</svg>

You can also use Yoksel's data-URL converter.
This way, your data-URL is more readable.

Upvotes: 3

Mugentoki
Mugentoki

Reputation: 1616

Safari has some problems with resizing SVG images, in the case the viewBox attribute is missing.
I can't tell if this is an intended behaviour or some sort of bug. But it's around for a while now.
Adding the attribute on your above example, fixed that behaviour and the mask gets a crisp edge.

Not sure why other changes on your page randomly seem to "fix" or "break" the mask (in terms of blurriness).


Your SVG

<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none">
...
</svg>

With viewport property

<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="none" viewbox="0 0 48 48">
...
</svg>

And working example based on your code

<html>
<head>
    <style>
    .logo {
        width: 96px;
        height: 96px;
        -webkit-mask-size: contain;
        mask-size: contain;
        -webkit-mask-image:
            url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgZmlsbD0ibm9uZSIgdmlld2JveD0iMCAwIDQ4IDQ4Ij48bWFzayBpZD0iYSIgc3R5bGU9Im1hc2stdHlwZTphbHBoYSIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeD0iMCIgeT0iMCIgd2lkdGg9IjQ4IiBoZWlnaHQ9IjQ4Ij48cGF0aCBkPSJNNDggMjRjMCAxOS4yMDUtNC43OTUgMjQtMjQgMjRTMCA0My4yMDUgMCAyNCA0Ljc5NSAwIDI0IDBzMjQgNC43OTUgMjQgMjR6IiBmaWxsPSIjZmZmIi8+PC9tYXNrPjxnIG1hc2s9InVybCgjYSkiPjxwYXRoIGZpbGw9IiMwMDAiIGQ9Ik0wIDBoNDh2NDhIMHoiLz48L2c+PC9zdmc+);
        mask-image:
            url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgZmlsbD0ibm9uZSIgdmlld2JveD0iMCAwIDQ4IDQ4Ij48bWFzayBpZD0iYSIgc3R5bGU9Im1hc2stdHlwZTphbHBoYSIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeD0iMCIgeT0iMCIgd2lkdGg9IjQ4IiBoZWlnaHQ9IjQ4Ij48cGF0aCBkPSJNNDggMjRjMCAxOS4yMDUtNC43OTUgMjQtMjQgMjRTMCA0My4yMDUgMCAyNCA0Ljc5NSAwIDI0IDBzMjQgNC43OTUgMjQgMjR6IiBmaWxsPSIjZmZmIi8+PC9tYXNrPjxnIG1hc2s9InVybCgjYSkiPjxwYXRoIGZpbGw9IiMwMDAiIGQ9Ik0wIDBoNDh2NDhIMHoiLz48L2c+PC9zdmc+);
        background-image:
            url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTAgMGgyMHYyMEgweiIvPjwvc3ZnPg==);
            background-size: cover;
    }
    </style>
</head>
<body>
    <div class="logo"/>
</body>
</html>

Upvotes: 0

Related Questions