Elements with position: relative with SVG clip paths not displaying in Safari
Asked Answered
S

3

5

I have a web page in which I am using an SVG clip path applied to one of the page's HTML elements.

SVG element:

<svg height="0" width="0">
    <defs>
        <clipPath id="clip">
            <path d="M150 0 L75 200 L225 200 Z" />
        </clipPath>
    </defs>
</svg>

HTML element the clipping path is applied to

<div id="clipMe"> </div>

CSS defining the clip

#clipMe {
    clip-path: url(#clip);
    -webkit-clip-path: url(#clip);
    width: 200px;
    height: 200px;
    background-color: red;
}

On the same page, I have various elements, some of which are relatively positioned:

<div style="position: relative">
    <strong>My parent is relative</strong>
</div>

In Safari (8.0.4) only, these relatively positioned elements are not being displayed as long as the linkage from the #clipMe div to the clipPath (within the SVG element) is intact.

Latest versions of FF and Chrome display as expected.

Changing the position: property to anything other than relative displays everything as expected.

Disabling the clipping path (either by removing the SVG element all together or removing the clip-path: property from the CSS) displays everything as expected as well.

JSfiddle:

Again, this is Safari only. It took me a while to isolate it down to being about the SVG clipping path and position: relative so I'm guessing there may other situations with similar results.

Has anyone run into this or have any suggestions for getting those relatively positioned s to display?

EDIT
It may be that this a Mac thing. Although it displays as expected in Chrome and Firefox in OSX, it does not display the relatively positioned DIVs in any browser on iOS.

Any ideas?

Siddon answered 24/4, 2015 at 6:35 Comment(1)
I don't agree with the title change. It implies that the element with the clip path being applied is not displaying. This is not the case; the clipped element is displaying fine. It is the other element on the page with position:relative that was not displaying. My .02.Siddon
P
10

Try using transform: translateZ(1px) on the clipped element. If it's not showing on mobile, you may need to include the other prefixes as well. Demo

It forces hardware acceleration (essentially the browser pays more attention to rendering it) by putting it on the GPU.


Edit: These days you can probably use will-change: transform to do the same thing. But some things may still require the translateZ trick.

Parsimonious answered 25/4, 2015 at 1:22 Comment(9)
Boom! I was hoping for a solution of this nature. Thanks! It definitely solved the problem in my example. I'll report back as to whether or not it stood up in my actual application. Are there any resources around that aggregate good tips like that?Siddon
@Siddon StackOverflow is one :PParsimonious
touche =) Is there any other way to force hardware acceleration? This solution fixes the issue with the elem not being displayed at all and in turn causes a new one: In my "real" implementation, have a pseudo-element (created via ::before) that needs to be overlapped by the relatively positioned element. To achieve this, I assign z-index: -1 to the pseudo-element. It works great until I add the -webkit-transform:translateZ(1px) at which point the pseudo-element z-index seems to reset causing it to stack on top of the main element. jsfiddle.net/daveh0/64awcv0p/6Siddon
@Siddon I don't believe there is another way currently. In the future we may have the will-change property which does roughly the same thing, but it's not implemented yetParsimonious
is there another way to manipulate the stacking order of elements then?Siddon
@Siddon Not that I know of using the current pseudo-element setup. You could try attaching the pseudo element to a parent instead jsfiddle.net/64awcv0p/8 Even if it's one that you add just for that effectParsimonious
Yup. I was REEEEEEEALLY hoping to find a way to do this without having to change any markup as it will have to be applied to every text input within my app (which is a lot), but this seems to be the best solution. Thanks for helping me get here.Siddon
Find and replace/multiple cursors are wonderful things. Feel free to drop by chat anytime you need helpParsimonious
Hello, I am here from the future (at the moment), and this still havent been fixed. But, the hack works just fine, thank you people from the past for saving the future!Vanpelt
O
0

two things:

  1. using css set display:block; to any thing that is position:relative;
  2. try clear:both; to anything that is position:relative;

I do not have safari version you are using to test on at this moment, but I know from prior experience when working with position:relative; you may need to clear or set display to block.

EDIT: may have found the issue.

Browser support for clip-path is partial in safari http://caniuse.com/#feat=css-clip-path

You should us the prefix -webkit-clip-path:

Ossa answered 24/4, 2015 at 6:53 Comment(9)
is it just the svg that is not displaying in safari version? If so it may be a browser compatibility issue. Some browsers do not support svg.Ossa
after viewing this caniuse.com/#feat=svg I found that safari version 8 is compatibleOssa
As I stated in my question, it is the elements with position:relative that are not displaying. The element on which the SVG clipping path is applied is displaying fine.Siddon
in the example you provided above the div style="position:relative;" does not have the semi colon at the endOssa
Also, you do NOT have any position:relative divs nested within another position:relative div correct?Ossa
that would not make a difference. But you can see the code in the jsfiddle I posted a link to.Siddon
I looked at your jsfiddle code. You refer to elements with position:relative as if there are more than one. In jsfiddle you only have one style with position:relative. That is why I asked if about the other is being nested. And yes, it does make a difference with how its coded when they are nested. Also, you have -webkit-clip-path after clip-path. -webkit-clip-path needs to be listed first.Ossa
thanks for the suggestions, but you're not offering solutions to my problem. The element with the SVG clipping path is displaying fine. It is any other element on the page with position:relative that is not being displayed at all.Siddon
I'm sorry I couldn't be of more help. I checked the code you provided in my version of safari and it is fine , but I don't have your version. I wish I could be of more helpOssa
J
0

You also can write:

transform: translateZ(0);

It works, but it is still a Safari bug.

Jaundiced answered 19/10, 2022 at 18:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.