CSS clip-path not working in Safari with children/pseudo elements - css

I got a pretty basic SVG clip-path:
<svg width="0" height="0">
<defs>
<clipPath id="line">
<path d="..." />
</clipPath>
</defs>
</svg>
Which i wanna use w/ CSS:
div {
clip-path: url(#line);
&:before {
...
}
}
It's working fine with Google Chrome, but not showing at all in Safari.
Also tried adding the -webkit- prefix.
Here's a live demo: https://jsfiddle.net/1dtpLg8y/
Its actually working if you get rid of the :before element: https://jsfiddle.net/fp5mouLn/
Here's a working SVG only version: https://jsfiddle.net/3gt67cLh/1/ but would love to do this with CSS.
Expected outcome:
Not showing anything in Safari.

Adding overflow:hidden to your line div seems to solve this issue.
(tested on iOs safari)
.line {
-webkit-clip-path: url(#line);
clip-path: url(#line);
background-color: #ccc;
width: 196px;
height: 6px;
position: relative;
overflow: hidden;
}
.line:before {
content: "";
width: 80px;
height: 80px;
background: radial-gradient(red, transparent 35%);
position: absolute;
left: -30px;
top: -36px;
}
body {
display: grid;
place-items: center;
min-height: 100vh;
}
<div class="line"></div>
<svg width="0" height="0">
<defs>
<clipPath id="line">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M0 5C0 4.65482 0.279822 4.375 0.625 4.375H5C8 4 9.11049 0.375 10 0.375C11 0.375 12 4 15 4.375H195.375C195.72 4.375 196 4.65482 196 5V5C196 5.34518 195.72 5.625 195.375 5.625H15C12 5.5 10 1.8 10 1.8C10 1.8 8 5.5 5 5.625H0.625C0.279822 5.625 0 5.34518 0 5V5Z"
fill="black"
/>
</clipPath>
</defs>
</svg>

If herrstrietzel's solution does not work, try "filter: hue-rotate(0deg);"
I had a similar problem, and adding "overflow:hidden" did not work, but adding "filter: hue-rotate(0deg)" did.

Related

Is there a way to cut out an svg path from another svg but leave remaining shape?

I have 2 main svgs one is a LOGO, and the other is a PILL shape I wish to cut out from the logo path. I have them in my index in <SVG> format. 4 letters in the logo needs to have each a cutout of this pill shape. I currently put all 4 paths of the pill svg into <clipPath> and tried cutting out the first pill shape from the 1st letter however I didn't get the desired result. I will attach an image of what I got vs what I wanted. Any help would be appreciated.
What I want to see -
[1]: https://i.stack.imgur.com/5RqXk.png
What happened when I tried clip path -
[2]: https://i.stack.imgur.com/WqRkl.png
I'm providing SVG code of the 1 letter and 1 pill shape for short demo purposes.
JS / REACT
<div className="wrapper-logo">
<svg className="App-logo" viewBox="0 0 375 84" fill="#DB3232" xmlns="http://www.w3.org/2000/svg">
<path className="LETTER-P" d="M39.3,6.1c9.59-.72,18.89,2.31,26.17,8.58,14.99,12.98,16.72,35.69,3.68,50.69-12.98,15.07-35.76,16.8-50.75,3.82-2.52-2.24-4.76-4.83-6.63-7.64v14.13c0,1.59-1.3,2.88-2.88,2.88s-2.88-1.3-2.88-2.88V41.94c0-8.58,3.1-16.94,8.72-23.43,6.27-7.28,14.99-11.68,24.58-12.4Z"/></svg>
<svg className="App-pill" viewBox="0 0 375 84" fill="#DB3232" xmlns="http://www.w3.org/2000/svg"><defs>
<clipPath id="pill-1" ><path className="pill-1" d="M47.3377 18.8021L18.8226 47.1101C13.7279 52.1678 13.7293 60.3942 18.8258 65.3743C23.9223 70.4298 32.2122 70.4281 37.2309 65.3704L65.746 37.0624C68.2554 34.5713 69.5477 31.2502 69.5471 27.9295C69.5465 24.6087 68.253 21.2882 65.7428 18.7982C60.7223 13.7426 52.4325 13.7444 47.3377 18.8021Z" fill="#EFE5DC"/></clipPath>
</svg>
</div>
CSS
.App-logo {
min-width: 100%;
pointer-events: none;
}
.App-pill {
min-width: 100%;
margin-top: -20px;
pointer-events: none;
position: absolute;
z-index: 2;
top: 0;
left: 0;
}
/* LETTER */
.LETTER-P {
clip-path: url(#pill-1);
}
/* PILL */
.pill-1 {
/* mask-composite: exclude; */
transform: rotate(204deg);
transform-origin: 42px 42px;
}
Yes, the mask was the best solve as I had to rotate the shapes in CSS. My solution was to make a mask in HTML and put each letter and pill in there. The mask layer should have all the layers you want to use in this process, make the layer you want to hide - black while the ones that should be seen is white. demonstrated below -
html
<div className="wrapper-logo">
<svg className="App-logo" viewBox="0 0 375 84" fill="#DB3232" xmlns="http://www.w3.org/2000/svg">
<path className="LETTER-P" d="M39.3,6.1c9.59-.72,18.89,2.31,26.17,8.58,14.99,12.98,16.72,35.69,3.68,50.69-12.98,15.07-35.76,16.8-50.75,3.82-2.52-2.24-4.76-4.83-6.63-7.64v14.13c0,1.59-1.3,2.88-2.88,2.88s-2.88-1.3-2.88-2.88V41.94c0-8.58,3.1-16.94,8.72-23.43,6.27-7.28,14.99-11.68,24.58-12.4Z"/></svg>
<svg className="App-pill" viewBox="0 0 375 84" fill="#DB3232" xmlns="http://www.w3.org/2000/svg"><defs>
<mask id="mask-p">
<path className="LETTER-P" d="M39.3,6.1c9.59-.72,18.89,2.31,26.17,8.58,14.99,12.98,16.72,35.69,3.68,50.69-12.98,15.07-35.76,16.8-50.75,3.82-2.52-2.24-4.76-4.83-6.63-7.64v14.13c0,1.59-1.3,2.88-2.88,2.88s-2.88-1.3-2.88-2.88V41.94c0-8.58,3.1-16.94,8.72-23.43,6.27-7.28,14.99-11.68,24.58-12.4Z" fill="white"/>
<path className="pill-1" d="M47.3377 18.8021L18.8226 47.1101C13.7279 52.1678 13.7293 60.3942 18.8258 65.3743C23.9223 70.4298 32.2122 70.4281 37.2309 65.3704L65.746 37.0624C68.2554 34.5713 69.5477 31.2502 69.5471 27.9295C69.5465 24.6087 68.253 21.2882 65.7428 18.7982C60.7223 13.7426 52.4325 13.7444 47.3377 18.8021Z" fill="black"/>
</mask>
</defs>
</svg>
</div>
CSS
.LETTER-P {
mask: url(#mask-p);
}
.pill-1 {
transform: rotate(0deg);
transform-origin: 42px 42px;
}

SVG ClipPath: Why does applying the clip path to a DIV have different results to an IMAGE?

I need to create a set of 3 triangles that each have content in them (images, copy, etc).
I have setup this Pen to show roughly what I'm trying to achieve: https://codepen.io/andystent/pen/OJyNdmB
And here is an image for quick reference:
In this example the "Top" and "Left" triangles are IMAGES with the clip-path applied and displaying perfectly.
The "Right" triangle (with the red background) is a DIV with the clip-path applied but the proportions are wrong.
It should look like a mirrored version of the "Left" triangle.
When I apply it to an image it is perfect but when I apply to the div it is not. What is the best way to do this?
I am new to SVG so it is extremely likely that I am not doing this correctly. I have looked at numerous posts and the method I have tried is from a few of those but without success... so now I'm reaching out to you geniuses...
Here's the HTML and CSS for the red "Right" triangle with the clip applied to the DIV in the CSS:
#right-wrapper {
position: absolute;
width: 50%;
height: 100%;
right: 0;
padding: 40px 20px;
box-sizing: border-box;
}
#right-content-div {
background-color: red;
height: 100%;
width: 100%;
position: absolute;
top: 0;
right: 0;
clip-path: url(#clip-path-right);
-webkit-clip-path: url(#clip-path-right);
display: flex;
justify-content: center;
align-items: center;
}
<div id="right-wrapper">
<svg width="100%" height="100%" viewBox="0 0 1220 1214" preserveAspectRatio="none">
<defs>
<clipPath id="clip-path-right">
<path d="M1232,1212.58943 L1232,4.82844551 C1232,3.17159126 1230.65685,1.82844551 1229,1.82844551 C1228.53907,1.82844551 1228.08435,1.93465364 1227.67111,2.13882722 L18.145562,599.743544 C13.1941115,602.189966 11.1633848,608.187127 13.6098071,613.138577 C14.582638,615.107544 16.1765951,616.701501 18.145562,617.674332 L1227.67111,1215.27905 C1229.15654,1216.01298 1230.95569,1215.40376 1231.68962,1213.91832 C1231.89379,1213.50508 1232,1213.05036 1232,1212.58943 Z" id="path-1">
</path>
</clipPath>
</defs>
<div id="right-content-div" preserveAspectRatio="none">
<h1>test heading</h1>
</div>
<!-- <image clip-path="url(#clip-path-right)" height="100%" width="100%" preserveAspectRatio="none" xlink:href="https://www.w3schools.com/css/klematis_big.jpg" /> -->
</svg>
</div>
----- UPDATE: -----
As suggested in the comments, I have created a simplified Pen that gets to the heart of what I'm trying to achieve and the embedded HTML and CSS is below.
Essentially I am trying to get the red <div> to be clipped exactly like the <image>.
https://codepen.io/andystent/pen/RwWRjLd
#right-content-div {
background-color: red;
height: 100%;
width: 100%;
position: absolute;
top: 0;
clip-path: url(#clip-path-right);
-webkit-clip-path: url(#clip-path-right);
}
<svg width="20%" height="20%" viewBox="0 0 1220 1214">
<defs>
<clipPath id="clip-path-right">
<path d="M1232,1212.58943 L1232,4.82844551 C1232,3.17159126 1230.65685,1.82844551 1229,1.82844551 C1228.53907,1.82844551 1228.08435,1.93465364 1227.67111,2.13882722 L18.145562,599.743544 C13.1941115,602.189966 11.1633848,608.187127 13.6098071,613.138577 C14.582638,615.107544 16.1765951,616.701501 18.145562,617.674332 L1227.67111,1215.27905 C1229.15654,1216.01298 1230.95569,1215.40376 1231.68962,1213.91832 C1231.89379,1213.50508 1232,1213.05036 1232,1212.58943 Z" id="path-1">
</path>
</clipPath>
</defs>
<image clip-path="url(#clip-path-right)" height="100%" width="100%" preserveAspectRatio="none" xlink:href="https://www.w3schools.com/css/klematis_big.jpg" />
</svg>
<div id="right-content-div" preserveAspectRatio="none">
<h1>test heading</h1>
</div>
Here is an idea where I will be using mask instead of clip-path. The main trick to correctly set the viewBox (you already have it in your code) add preserveAspectRatio="none" then have a mask size of 100% 100%
.box {
width:200px;
height:200px;
display:inline-block;
background:red;
}
.mask {
-webkit-mask:url('data:image/svg+xml;utf8,<svg preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1220 1214"> <path d="M1232,1212.58943 L1232,4.82844551 C1232,3.17159126 1230.65685,1.82844551 1229,1.82844551 C1228.53907,1.82844551 1228.08435,1.93465364 1227.67111,2.13882722 L18.145562,599.743544 C13.1941115,602.189966 11.1633848,608.187127 13.6098071,613.138577 C14.582638,615.107544 16.1765951,616.701501 18.145562,617.674332 L1227.67111,1215.27905 C1229.15654,1216.01298 1230.95569,1215.40376 1231.68962,1213.91832 C1231.89379,1213.50508 1232,1213.05036 1232,1212.58943 Z" /> </svg>') 0 0/100% 100%;
mask:url('data:image/svg+xml;utf8,<svg preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1220 1214"> <path d="M1232,1212.58943 L1232,4.82844551 C1232,3.17159126 1230.65685,1.82844551 1229,1.82844551 C1228.53907,1.82844551 1228.08435,1.93465364 1227.67111,2.13882722 L18.145562,599.743544 C13.1941115,602.189966 11.1633848,608.187127 13.6098071,613.138577 C14.582638,615.107544 16.1765951,616.701501 18.145562,617.674332 L1227.67111,1215.27905 C1229.15654,1216.01298 1230.95569,1215.40376 1231.68962,1213.91832 C1231.89379,1213.50508 1232,1213.05036 1232,1212.58943 Z" /> </svg>') 0 0/100% 100%;
}
<div class="box mask"></div>
<div class="box mask" style="width:300px;"></div>
<div class="box mask" style="height:300px;"></div>
<img src="https://i.picsum.photos/id/1074/200/200.jpg" class="mask">

Adding image to SVG path

I found some cool SVG code from and started trying things out. Now I cleared up most of the random code but now I want to add an image on the grey block, but cannot seem to get it to work. I tried a few tips from StackOverflow already like adding random classes to it and creating extra id's in the code but it still won't work. I would like to create something like this.
.slide {
position: relative;
padding: 8% 0;
}
.slide__image svg {
display: block;
width: 100%;
max-width: 560px;
margin: auto;
}
.slide__bg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
}
<svg>
<g id="p">
<path opacity=".2" d="M0 2h252s-3.3 40.7-2.7 128.3C249 216 252 272 252 272s-88-2-124.3-
2C91.3 270 0 272 0 272V0z"/>
<path fill="#f4f3f1" d="M0 0h248v270H0z"/>
<path fill="#4f5150" d="M8 10h233v203H8z"/>
</g>
<g id="polaroid">
<use xlink:href="#p" transform="rotate(15)" x="175" y="50"/>
<use xlink:href="#p" transform="rotate(-5)" x="5" y="25"/>
</g>
</svg>
Thanks for looking at the question!

css svg filter safari not working

I am using a css filter property by applying an svg feColorMatrix to it. It works on Firefox and Chrome very well. But it does not work on safari. I have been playing with the values, indentation, vendor prefixes and have not been able to successfully apply my filter in safari.
Can anyone help me identify why my filter does not work in Safari?
You can view the demo here
https://codepen.io/Fallenstedt/pen/OvYGjV
My svg filter and video element:
<svg class="defs-only">
<filter
id="blue-tint"
color-interpolation-filters="sRGB"
x="0"
y="0"
height="100%"
width="100%">
<feColorMatrix
type="matrix"
values="0 0 0 0 0
0.75 0 0 0 0
1.265 0 0 0 0
0 0 0 1 0
"/>
</filter>
</svg>
<div class="background-vid">
<video id="video"
class="lazy"
autoplay
loop
muted>
<source src="https://storage.googleapis.com/coverr-main/mp4/Cloud_Surf.mp4" type="video/mp4">
</video>
</div>
My scss:
html, body {
margin: 0;
padding: 0;
}
.defs-only {
position: absolute;
height: 0;
width: 0;
overflow: none;
left: -100%;
}
.background-vid {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
position: absolute;
top: 0;
z-index: -1;
-webkit-filter: grayscale(100%) url(#blue-tint);
filter: grayscale(100%) url(#blue-tint);
video {
object-fit: cover;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
}
Your syntax is all correct and Safari is following the code path (if you replace that feColorMatrix with a feFlood/blue, it paints the area blue). I think what's happening is that SVG Filters on Safari are not very performant, so I think they punt when something gets too stressful like doing real-time video processing. If you replace the video with an image - this works fine.
(FWIW on my (very old) Mac, this doesn't work on Chrome/MacOS.)
If you use filters for svg elements in the css/scss file
filter: url(#filter_id);
Transfer the styles from the css/scss file into the svg file separately into styles, and everything will work, like this:
<svg>
...
<g id="group_id">
..
</g>
<filter id="filter_id" x="5.54736" y="0" width={width-11.3} height="80.0002" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood floodOpacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="10" result="effect1_foregroundBlur_326_868"/>
</filter>
<style>
{`
#group_id {
filter: url(#filter_id);
}
`}
</style>
</svg>

How to make an svg masked image compatible with firefox

I have some svg masked images that work perfectly in Chrome but does not work in Firefox. Basically my svg gives a shape to the image that the css is applied to and the end result is this .
This is my svg code
<svg width="0" height="0" viewBox="0 0 160 160">
<defs>
<clipPath id="shape">
<path d="M10,70 Q0,80 10,90 L70,150 Q80,160 90,150 L150,90 Q160,80 150,70 L90,10 Q80,0 70,10z" />
</clipPath>
</defs>
</svg>
<img src='http://i.imgur.com/NR6kefg.jpg' class='photo_rectangle_inverse' />
<img src='http://i.imgur.com/DXaH323.jpg' class='photo_rectangle_inverse' />
And this is my css
* {
padding: 0;
margin: 0;
}
.photo_rectangle_inverse {
height: 160px;
width: 170px;
-webkit-clip-path: url(#shape);
clip-path: url(#shape);
position: relative;
-webkit-transform: translateZ(1px)
}
Here is a Jsfiddle of all that. This works perfectly in Chrome but not In the latest version of Firefox as at now on windows (FF 40.0.2) .
I went to this Firefox article but could not find why this is not working in Firefox ?
How to make this svg masked image compatible with firefox ?
Thanks

Resources