Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't CSS clip-path with SVG work in Safari?

I have an inline svg and a background image on the masthead. I am using css clip-path to 'clip' out the svg animation with the image below.

I have it working great in firefox and chrome but safari doesn't apply any of the clipping/masking at all.

I checked caniuse spec's before starting this project and it states the same rules and exceptions that apply to chrome, I just tested with chrome first and it worked so I continued on it figuring safari would have the same treatment.

I have been scratching my head trying to figure out how to get the clipping to work properly in safari with no avail.

How can I get this to work in safari? Pen for reference: https://codepen.io/H0BB5/pen/Xpawgp

HTML

<clipPath id="cross">
    <rect y="110" x="137" width="90" height="90"/>
    <rect x="0" y="110" width="90" height="90"/>
    <rect x="137" y="0" width="90" height="90"/>
    <rect x="0" y="0" width="90" height="90"/>
 </clipPath>

CSS

#clipped {
  margin-bottom: 20px;
  clip-path: url(#cross);
}
like image 281
h0bb5 Avatar asked Jan 25 '17 19:01

h0bb5


People also ask

Can I use clip path SVG?

Support for clip-path in SVG is supported in all browsers with basic SVG support.

What is SVG clip rule?

« SVG Attribute reference home. The clip-rule attribute only applies to graphics elements that are contained within a <clipPath> element. The clip-rule attribute basically works as the fill-rule attribute, except that it applies to <clipPath> definitions.


3 Answers

You need the -webkit- prefix. I can confirm your circle and inset options work in Safari after adding the -webkit- prefix to your CSS and JS.

CanIUse.com reports partial support for Safari if using the -webkit- prefix: http://caniuse.com/#search=clip-path

CSS:

#clipped {
  margin-bottom: 20px;
  clip-path: url(#cross);
  -webkit-clip-path: url(#cross);
}

JS:

var clipPathSelect = document.getElementById("clipPath");
clipPathSelect.addEventListener("change", function (evt) {
  document.getElementById("clipped").style.clipPath = evt.target.value;
  document.getElementById("clipped").style.webkitClipPath = evt.target.value;
});

Forked CodePen: https://codepen.io/techsock/pen/JEyqvM


Update

It appears that this may be an issue with Safari's implementation of clip-path. There is a Master Bug reported regard webkit issues with clip-path. In JSFiddle, Safari will occasionally render the SVG clip path containing multiple rect elements correctly, but not reliably (see attached screenshots below). There does not appear to be an extremely reliable workaround. It also is noted on the MDN page you pulled this example from: https://developer.mozilla.org/en-US/docs/Web/CSS/clip-path#Browser_compatibility. MDN lists Safari as No Support.

JSFiddle behavior screenshots:

✗ Incorrect Incorrect

✗ Incorrect Incorrect

✓ Correct Correct

like image 182
hopkins-matt Avatar answered Sep 29 '22 12:09

hopkins-matt


Just need to add -webkit- prefix:

-webkit-clip-path: polygon(50% 0%, 1000% 0%, 50% 100%, -1000% 0%);
like image 22
Murtaza JAFARI Avatar answered Oct 01 '22 12:10

Murtaza JAFARI


tl;dr: Use transform: translateZ(0); on the element the clip-path is applied to.

I had a similar issue recently where a referenced SVG clip-path would not render properly in Safari. I'm still not sure what the cause of the issue is, but forcing the element to its own compositor layer seems to fix it.

Any property that forces the element to render on its own layer will do.

transform: translateZ(0);

will-change: transform;

etc..

edit: This is on top of using the proper prefixes for Webkit-based browsers.

like image 27
Andreas Myriounis Avatar answered Sep 29 '22 12:09

Andreas Myriounis