clipPath on webkit does not render - css

Enthused by this article, I tried to apply a gradient clip-path to my relatively simple shape (an O letter converted to curves).
It works perfectly under Firefox, but as soon as I try it under a webkit, I see absolutely nothing.
I've tried to fix it, I've split it in simple parts, trying both Amit Sheen code with mine, and the only thing that make it fail is using my path instead of his. If I don't use clipPath, the path is rendered as expected, but as soon as I clip it, it just vanishes. I can't figure out what the problem is.
Can you help me?
.gradient {
width: 157px;
height: 157px;
background: linear-gradient(90deg, rgba(6,94,115,0.7959383582534576) 0%, rgba(207,241,255,1) 100%);
border-radius: 50%;
}
<svg viewBox="0 0 1000 400" xmlns="http://www.w3.org/2000/svg">
<clipPath id="clip">
<path d="M547.923,151.764C504.147,151.764 471.027,185.46 471.027,228.372C471.027,270.996 504.147,304.98 547.923,304.98C591.987,304.98 625.107,270.996 625.107,228.372C625.107,185.46 591.987,151.764 547.923,151.764ZM547.923,269.844C523.731,269.844 508.467,251.124 508.467,228.372C508.467,205.62 523.731,186.9 547.923,186.9C572.403,186.9 587.667,205.62 587.667,228.372C587.667,251.124 572.403,269.844 547.923,269.844Z" />
</clipPath>
<foreignObject x="470" y="150" width="157" height="157" clip-path="url(#clip)">
<div class="gradient" xmlns="http://www.w3.org/1999/xhtml"></div>
</foreignObject>
</svg>

You may need to transform your path so that it's left upper corner falls in the point (0,0). This is needed in chrome but won't work in firefox unless the foreign object has x="0" y="0". For this reason instead of giving a x and y attributes to the foreign object I translated it to the needed point.
svg{background:silver}
<svg viewBox="0 0 1000 400">
<foreignObject width="157" height="157" transform="translate(471,151)" clip-path="url(#clip)">
<div style="height:100%;background:gold"> </div>
</foreignObject>
<clipPath id="clip">
<path id="p" transform="translate(-471,-151)" d="M547.923,151.764C504.147,151.764 471.027,185.46 471.027,228.372C471.027,270.996 504.147,304.98 547.923,304.98C591.987,304.98 625.107,270.996 625.107,228.372C625.107,185.46 591.987,151.764 547.923,151.764ZM547.923,269.844C523.731,269.844 508.467,251.124 508.467,228.372C508.467,205.62 523.731,186.9 547.923,186.9C572.403,186.9 587.667,205.62 587.667,228.372C587.667,251.124 572.403,269.844 547.923,269.844Z" />
</clipPath>
</svg>

Related

CSS stacking context affecting SVG opacity?

I came across an "issue happening on Safari" raised which finally lead me to discover a very different behaviour on some scenario on Chromium based browsers vs. Firefox vs. Safari, with 3 different results. But I can't really find any reference on specifications about if there is any reason for what any of them do or which is the right behaviour.
Scenario can be checked on this snippet - code is not much interesting, preview is.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display: none;">
<symbol id="flag" viewBox="0 0 600 200">
<defs>
<linearGradient id="prefix__e" x1="27.243%" x2="72.757%" y1="67.663%" y2="32.348%">
<stop offset="0%"/>
<stop offset="100%" stop-opacity="0"/>
</linearGradient>
<path id="prefix__a" d="M0 0H700V600H0z"/>
</defs>
<g style="mix-blend-mode:multiply" fill="none" fill-rule="evenodd">
<mask id="prefix__b" fill="#fff">
<use xlink:href="#prefix__a"/>
</mask>
<g style="mix-blend-mode:multiply" mask="url(#prefix__b)">
<g>
<g>
<path fill="#592C82" d="M349.941 0L0 95.825 0 469.766 0 977.167 350.059 1071.707 700 977.167 700 95.825 700 95.706z" transform="matrix(1 0 0 -1 0 600) translate(0 95.043)"/>
<path fill="url(#prefix__e)" fill-opacity=".6" d="M349.941 0L0 95.825 0 469.766 0 977.167 350.059 1071.707 700 977.167 700 95.825 700 95.706z" transform="matrix(1 0 0 -1 0 600) translate(0 95.043)"/>
</g>
</g>
</g>
</g>
</symbol>
</svg>
<div>
<div style="background: blue; height: 40px">below svg is at same stacking context</div>
<div style=" transform: none">
<svg width="300" height="100" style="margin-left: 50px; margin-top: -20px;">
<use xlink:href="#flag"></use>
</svg>
</div>
<hr>
<div style="background: blue; height: 40px">below svg has own stacking context (translate)</div>
<div style=" transform: translate(0, 0 );">
<svg width="300" height="100" style="margin-left: 50px; margin-top: -20px;">
<use xlink:href="#flag"></use>
</svg>
</div>
<hr>
<div style="background: blue; height: 40px">below svg has own stacking context (opacity)</div>
<div style=" filter: opacity(100%);">
<svg width="300" height="100" style="margin-left: 50px; margin-top: -20px;">
<use xlink:href="#flag"></use>
</svg>
</div>
</div>
SVG is purple semi transparent, blue divs are just behind the SVG. When SVG is transparent and overlaps other HTML content, it sometimes allows to see the content below, sometimes it doesn't. My conclusions are next:
On Chromium based browsers, transparency works as expected - mixing colours with the background element until the SVG is placed in a different stacking context, then opacity stops allowing seeing behind elements from other stacking contexts.
On Safari for Mac, it seems to work similar to Chromium but maybe in a buggy way? When in the same stacking context transparency works. If you move the SVG into a new stacking context using some properties like filter transparency stops, but other properties don't stop the transparency - like transform.
On Firefox, transparency simply don't work, elements behind the transparent SVG are not visible through it, even on same stacking context.
Any idea about the specs saying something about this?
Thank you in advance.

Transforming an element inside an SVG in Microsoft Edge Doesn't Work

For some reason Microsoft Edge doesn't allow you to do transforms on elements inside of an SVG. Fills work fine (so I know the element targeting is working) but transforms are entirely ignored. This works fine in chrome and as far as I can tell, should work fine in Edge too.
HTML:
<div class="test-container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 300 400" xmlSpace="preserve">
<g id="Type">
<g>
<rect x="100" class="st1" id="rect1" width="100" height="100"/>
<rect x="100" y="100" class="st1" id="rect2" width="100" height="100"/>
</g>
</g>
</svg>
</div>
CSS:
.test-container {
width: 100px;
}
#rect1 {
fill: blue;
transform: translate(50px);
}
#rect2 {
fill: red;
}
See codepen example here: http://codepen.io/dwolfand/pen/pEzQgy
Any ideas?
As of August 31, 2016, Microsoft Edge does not support CSS transforms on SVG elements. This is however being considered by the Edge team for a future release. Given the support across other browsers, status.microsoftedge.com lists this work as likely.
This may be related to an issue I ran into with the D3.js library. Shapes would come out filled with black, because the attribute properties that Edge generated (and no other browser) would always come out UPPERCASE, which the SVG standard doesn't support. Inspect the elements and see if the attributes are uppercased; if so, then it's a known issue in Edge.

IE 11 :after background size not working

I added a background-image inside the pseudo :after
::after {
content: '';
display: block;
position: absolute;
right: -2.5rem;
bottom: -1.5rem;
height: 9.5rem;
width: 9.5rem;
background-image: url('../img/icons/icon_logo.svg');
background-repeat: no-repeat;
// background-size: 100% auto;
background-size: cover;
}
But the image is way bigger than the actual size of the box.
Any idea how to solve this?
(Working fine in webkit browsers)
!!!Additional Information:
I tried other svg and it works great.
Works:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
<path fill="#FF6C00" d="M0 0h64v64H0z"/>
<path fill="#FFF" d="M33 0C22 0 13 9 ..."/>
</svg>
Does not work:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
<path fill="#FFF" d="M0 0h64v64H0z"/>
<defs>
<path id="a" d="M0 0h64v64H0z"/>
</defs>
<clipPath id="b">
<use xlink:href="#a" overflow="visible"/>
</clipPath>
<path fill="#277052" d="M43.7 51.8s-...."/>
<defs>
<path id="c" d="M0 0h64v64H0z"/>
</defs>
<clipPath id="d">
<use xlink:href="#c" overflow="visible"/>
</clipPath>
<path fill="#EE7203" d="M40.7 28.7c0 4.8-3..." clip-path="url(#d)"/>
<path fill="#1D1D1B" d="M43 10.9c.2.1.4 0..." clip-path="url(#d)"/>
</svg>
Read this link
Adobe Illustrator give me four options to declaring style sheet properties when saving graphics as an SVG file
Presentation Attributes
Style Attributes
Style Attributes (Entity Reference)
Style Elements
No problem using the first three ways to styling properties, but embedding style sheets into SVG content inside a element cause the problem!
I had similar issues rendering CSS in IE.
My solution:
Make sure you have a <!DOCTYPE> declaration before your html
Add the meta tag <meta http-equiv="X-UA-Compatible" content="IE=edge" > (this makes sure that your code always renders the cutting edge or most updated version of internet explorer; else, it can render from older versions and things get really messy.)
I hope that helps.
Try adding in display:block to the css.

Firefox and responsive SVG

Here is a thing.
I have a 700x700px image that i would need to mask with SVG.
For Chrome and Safari i did that by using -webkit-mask-box-image with external SVG and it works properly.
For Firefox, i used clip-path property, and again, it functions properly.
The responsive part is problem.On Chrome&Safari, that part is working nicely, but on Firefox only the main image is resized, mask stays the same.
I am a complete newbie at this and i tried tons of solutions that i found online and i really couldn’t make it work.
<style>
body {
background: yellow;
}
.img-mask {
-webkit-mask-box-image: url('http://imgh.us/mask_3.svg');
mask-border: url('http://imgh.us/mask_3.svg');
clip-path: url(#mask);
}
</style>
<img src="http://gto-live.com/wp-content/uploads/2015/04/charm-elegance-colorful-sofa-living-room-decor-718x718.jpg" class="img-mask">
enter code here
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="700" height="700" viewBox="0 0 700 700">
<clipPath id="mask">
<path d="M718.004,358.999 C718.004,160.726 557.272,-0.007 358.998,-0.007 C160.725,-0.007 -0.007,160.726 -0.007,358.999 C-0.007,557.272 160.725,718.005 358.998,718.005 C557.272,718.005 718.004,557.272 718.004,358.999 Z"/>
</clipPath>
</svg>
Any help would really really be gratefully appreciated!
Fiddle can be found here https://jsfiddle.net/y7zaw4bz/1/
You need to use objectBoundingBox units (and make the path run from 0 to 1) e.g.
body {
background: yellow;
}
img {
width: 100%;
}
.img-mask {
-webkit-mask-box-image: url('http://imgh.us/mask_3.svg');
mask-border: url('http://imgh.us/mask_3.svg');
clip-path: url(#mask);
}
<img src="http://gto-live.com/wp-content/uploads/2015/04/charm-elegance-colorful-sofa-living-room-decor-718x718.jpg" class="img-mask">
<svg preserveAspectRatio="xMidYMid" width="700" height="700" viewBox="0 0 700 700">
<clipPath id="mask" clipPathUnits="objectBoundingBox">
<path transform="scale(0.0014)" d="M718.004,358.999 C718.004,160.726 557.272,-0.007 358.998,-0.007 C160.725,-0.007 -0.007,160.726 -0.007,358.999 C-0.007,557.272 160.725,718.005 358.998,718.005 C557.272,718.005 718.004,557.272 718.004,358.999 Z"/>
</clipPath>
</svg>
Here I've scaled the path to correct the units 0.0014 is roughly 1 / 700

CSS Clip-path positioning issues

I have created a fairly simple shape using an SVG element which is then put into my CSS using clip-path. It should make the corners rounded for me but for some reason only 1 of the corners does the effect perfectly.
This is the shape:
<svg height="500" width="500">
<path fill="#555555" d="M50,0 L450,0 Q500,0 500,50 L500,400 Q500,450 450,450 L200,450 L175,500 L150,450 L50,450 Q0,450 0,400 L0,50 Q0,0 50,0z" />
</svg>
This is what happens when i use it as a clip-path
body {
background: #555;
}
img {
clip-path: url(#svgPath);
-webkit-clip-path: url(#svgPath);
}
<svg height="0" width="0">
<defs>
<clipPath id="svgPath">
<path fill="#FFFFFF" d="M50,0 L450,0 Q500,0 500,50 L500,400 Q500,450 450,450 L200,450 L175,500 L150,450 L50,450 Q0,450 0,400 L0,50 Q0,0 50,0z" />
</clipPath>
</defs>
</svg>
<img src="https://dummyimage.com/500" />
It seems to work perfectly within FireFox but shows the corners aren't cut correctly in Chrome apart from the bottom right corner.
The default units for the clip-path is userSpaceOnUse and this seems to calculate the coordinates of the path with reference to the root element. This is the reason why the clip-path seems like it is producing an incorrect output. Nullifying the margin and padding on the root element or absolutely positioning the element (like in the below snippet) should solve the issue.
body {
background: #555;
}
img {
position: absolute;
top: 0px;
left: 0px;
clip-path: url(#svgPath);
-webkit-clip-path: url(#svgPath);
}
<svg height="0" width="0">
<defs>
<clipPath id="svgPath">
<path fill="#FFFFFF" d="M50,0 L450,0 Q500,0 500,50 L500,400 Q500,450 450,450 L200,450 L175,500 L150,450 L50,450 Q0,450 0,400 L0,50 Q0,0 50,0z" />
</clipPath>
</defs>
</svg>
<img src="http://lorempixel.com/500/500/" />
However, in a real life scenario the actual element that has to be clipped could be present anywhere within the body and hence I think it is a much better approach to use the objectBoundingBox as the units like in the below snippet:
body {
background: #555;
}
img {
clip-path: url(#svgPath);
-webkit-clip-path: url(#svgPath);
}
<svg height="0" width="0">
<defs>
<clipPath id="svgPath" clipPathUnits="objectBoundingBox">
<path fill="#FFFFFF" d="M0.1,0 L0.9,0 Q1,0 1,0.1 L1,0.8 Q1,0.9 0.9,0.9 L0.4,0.9 L0.35,1 L0.3,0.9 L0.1,0.9 Q0,0.9 0,0.8 L0,0.1 Q0,0 0.1,0z" />
</clipPath>
</defs>
</svg>
<img src="https://dummyimage.com/500" />
As mentioned in the question itself, this behavior is visible only in Chrome and not Firefox for reasons unknown to me. Firefox produces an output similar to the expected one even when (a) extra padding + margin is added to the body and (b) when the image itself is wrapped inside another container which also has padding + margin.
The only case where Firefox's output matches with Chrome is when a padding is added directly to the img tag itself. I believe this happens because padding is part of the element and thus affects the coordinates.

Resources