19

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);
}
h0bb5
  • 609
  • 1
  • 7
  • 22

5 Answers5

31

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

Community
  • 1
  • 1
hopkins-matt
  • 2,763
  • 2
  • 15
  • 23
  • Thanks for the reply. You are correct about the -webkit- prefix, I had forgot to save it out in my pen, but if you look at your forked pen and select the 'cross' option it is still not working. This is because the Cross toggle is the only one referring to an SVG clip, the rest are just applying styles to the image. The clip-path is what is not functioning properly in safari. – h0bb5 Jan 25 '17 at 20:07
  • Yes, it appears to be the way you have constructed the SVG. I dropped another inline SVG into the pen, and it functioned correctly. I'll take a peek and see if I can see what's wrong. – hopkins-matt Jan 25 '17 at 20:19
  • Hey hopkins, I got that method of writing them directly from mozilla's guidelines: https://developer.mozilla.org/en-US/docs/Web/CSS/mask Which method did you write yours out that it worked? – h0bb5 Jan 26 '17 at 16:10
  • I've updated my answer with information regarding Safari's issue rendering `clip-path`. – hopkins-matt Jan 26 '17 at 17:44
  • now MDN says iOS safari supports `clip-path`, but I'm still facing `random` rendering – godblessstrawberry Apr 07 '21 at 15:32
  • @hopkins-matt Any idea if the bug is already fixed? Or when that will happen? I also have problems with it on a client website of me (where Chromium and Firefox work smooth). – ralphjsmit Jul 07 '21 at 08:30
3

Just need to add -webkit- prefix:

-webkit-clip-path: polygon(50% 0%, 1000% 0%, 50% 100%, -1000% 0%);
Murtaza JAFARI
  • 674
  • 7
  • 10
1

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.

0

For me my issue was that I had my IMG tag with position:relative

  • Ran across a similar issue. However, it seems the `position: relative` is not the issue, but rather applying any `z-index` to the element causes Safari to no longer render the mask or image. – Jason Mar 22 '23 at 15:33
0

I figured out the issue doesn't occur in storybook because storybook wraps their component in an Iframe.

This prompted me test my theory and lo and behold, you can fix the clip-path issue on safari by wrapping your component in an iframe.

I suggest looking at the accepted answer on this post: How to set iframe content of a react component

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 10 '22 at 09:44