Inline SVG path not working - css

I've been trying to get a inline svg clipping path to work but can't quite figure out why it isn't.
The first div in the snippet is the one that isn't working (#myClip)
The second is what it should look like.
The third div is all the same code but with a different path that does work.
So what's wrong with my first one? Any help is greatly appreciated.
#myDiv {
background: Red;
min-height: 400px;
-webkit-clip-path: url(#myClip);
clip-path: url(#myClip);
}
/* Div with a different clipping path that I don't want */
#myDiv-two {
background: Red;
min-height: 400px;
-webkit-clip-path: url(#myClipTwo);
clip-path: url(#myClipTwo);
}
<h2>Div with clip path that's not working</h2>
<div id="myDiv">
<svg width="0" height="0">
<clipPath id="myClip" clipPathUnits="objectBoundingBox">
<path d="M0,0V678.48s138.59-46.14,279.3-48.31,256.56,4.64,326.86,13.44S941.94,700.69,1115,688.48s205.35-15.91,325-40.13V0Z"/>
</clipPath>
</svg>
</div>
<h2>Original SVG</h2>
<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 690.45"><defs></defs><path d="M0,0V678.48s138.59-46.14,279.3-48.31,256.56,4.64,326.86,13.44S941.94,700.69,1115,688.48s205.35-15.91,325-40.13V0Z" fill="#F34862"/></svg>
<h2>Div with different clipping path</h2>
<div id="myDiv-two">
<svg width="0" height="0">
<clipPath id="myClipTwo" clipPathUnits="objectBoundingBox">
<path d="M0,0 1,0 1,0.9 C 1,0.9, 0.77,1, 0.5,1 0.23,1, 0,0.9,0,0.9z"/>
</clipPath>
</svg>
</div>

You have defined your clipping path to be clipPathUnits="objectBoundingBox". When you do that, the coordinates need to be between 0 and 1. (0,0) represents the top left of the element the clip is being applied to. And (1,1) represents the bottom right.
However your coordinates are much bigger than that. For example your initial line (M0,0V678.48) is from (0,0) to (0,678.48).

I would love an explanation as to why the coordinates need to be between 0 and 1 but I have made an SVG by hand instead of exporting from illustrator that is fairly close to my original using coordinates between 0 and 1 so it will work.
#myDiv {
background: Red;
min-height: 400px;
-webkit-clip-path: url(#myClip);
clip-path: url(#myClip);
}
<h2>New Clip path</h2>
<div id="myDiv">
<svg width="0" height="0">
<clipPath id="myClip" clipPathUnits="objectBoundingBox">
<path d="M0,0 1,0 1,0.86 C 1.1,.85, 0.9,1, 0.7,1 0.4,1, 0.3,0.8,0,1z"/>
</clipPath>
</svg>
</div>
<h2>Original SVG</h2>
<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 690.45"><defs></defs><path d="M0,0V678.48s138.59-46.14,279.3-48.31,256.56,4.64,326.86,13.44S941.94,700.69,1115,688.48s205.35-15.91,325-40.13V0Z" fill="#F34862"/></svg>

Related

SVG is not talking FULL 'width' of container

I am trying to make my svg full with width of the screen (container) but its not working. Could someone help me - please?
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320" preserveAspectRatio="none" class="first-svg">
<path fill="#27187F" fill-opacity="1" d="M0,192L60,170.7C120,149,240,107,360,106.7C480,107,600,149,720,170.7C840,192,960,192,1080,170.7C1200,149,1320,107,1380,85.3L1440,64L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path>
</svg>
css
.first-svg {
width: 100%;
height: 200px;
}
I am suing bootstrap for this project I am working (only for practice)
I have done the following and it seemed to work - I added the SVG inside a row.
<div class="row">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320" preserveAspectRatio="none" class="first-svg">
<path fill="#27187F" fill-opacity="1" d="M0,192L60,170.7C120,149,240,107,360,106.7C480,107,600,149,720,170.7C840,192,960,192,1080,170.7C1200,149,1320,107,1380,85.3L1440,64L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path>
</svg>
</div>

Using clipPathUnits="objectBoundingBox" makes clip path disappear

Problem:
I've created an SVG Clip Path which needs to be responsive, but when I try to use clipPathUnits="objectBoundingBox" in the clip path tag, it makes the target object disappear.
I made example snippets with and without. The first one shows as expected, but the second is completely hidden.
I've tested it with various simple shapes and paths which work fine, but I can't get clipPathUnits="objectBoundingBox" working with anything more complicated, not sure what I'm missing.
Snippet:
body {
background: #333;
}
#hero {
background: url(https://source.unsplash.com/random);
height: 120vh;
background-color: #ff0000;
width: 100vw;
background-size: cover;
clip-path: url(#wav);
}
#hero2 {
background: url(https://source.unsplash.com/random);
height: 120vh;
background-color: #ff0000;
width: 100vw;
background-size: cover;
clip-path: url(#wav2);
}
<div id="hero"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<clipPath id="wav" >
<path d="M815.8,19.7c-18.9,0-18.7,15.3-37.9,15.3-17.6,0-19.6-13-38-13-15,0-14.9,11.1-38,11.1C672.5,33.1,676,4.6,640,4.6s-40.1,39.9-79.8,39.9c-33,0-38.7-18-63-18s-32.8,15.9-49.9,15.9c-13.1,0-19.7-4-26.3-9.7h0c-6.5-5.6-13.2-13-26.3-13C375.8,19.7,376,35,356.9,35c-17.6,0-19.7-13-38-13-15.1,0-14.9,11.1-38,11.1C251.5,33.1,255,4.6,219,4.6s-40.1,39.9-79.8,39.9c-33,0-38.7-18-63-18S43.3,42.4,26.3,42.4c-13.1,0-19.7-4-26.3-9.7V562.6c6.5,5.6,13.2,12.9,26.2,12.9,18.9,0,18.7-15.2,37.9-15.2,17.6,0,19.6,12.9,38,12.9,15,0,14.9-11,38-11,29.4,0,25.9,28.5,61.9,28.5s40.1-39.9,79.8-39.9c33,0,38.7,18,63,18s32.8-15.9,49.9-15.9c13.1,0,19.7,4,26.3,9.6h0c6.5,5.7,13.2,13,26.3,13,18.9,0,18.7-15.2,37.8-15.2,17.6,0,19.7,12.9,38,12.9,15.1,0,14.9-11,38-11,29.4,0,25.9,28.5,61.9,28.5s40.1-39.9,79.8-39.9c33,0,38.7,18,63,18s32.9-15.9,49.9-15.9c13.1,0,19.7,4,26.3,9.6V32.7C835.5,27.1,828.8,19.7,815.8,19.7Z" />
</clipPath>
</svg>
<div id="hero2"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<clipPath id="wav2" clipPathUnits="objectBoundingBox">
<path d="M815.8,19.7c-18.9,0-18.7,15.3-37.9,15.3-17.6,0-19.6-13-38-13-15,0-14.9,11.1-38,11.1C672.5,33.1,676,4.6,640,4.6s-40.1,39.9-79.8,39.9c-33,0-38.7-18-63-18s-32.8,15.9-49.9,15.9c-13.1,0-19.7-4-26.3-9.7h0c-6.5-5.6-13.2-13-26.3-13C375.8,19.7,376,35,356.9,35c-17.6,0-19.7-13-38-13-15.1,0-14.9,11.1-38,11.1C251.5,33.1,255,4.6,219,4.6s-40.1,39.9-79.8,39.9c-33,0-38.7-18-63-18S43.3,42.4,26.3,42.4c-13.1,0-19.7-4-26.3-9.7V562.6c6.5,5.6,13.2,12.9,26.2,12.9,18.9,0,18.7-15.2,37.9-15.2,17.6,0,19.6,12.9,38,12.9,15,0,14.9-11,38-11,29.4,0,25.9,28.5,61.9,28.5s40.1-39.9,79.8-39.9c33,0,38.7,18,63,18s32.8-15.9,49.9-15.9c13.1,0,19.7,4,26.3,9.6h0c6.5,5.7,13.2,13,26.3,13,18.9,0,18.7-15.2,37.8-15.2,17.6,0,19.7,12.9,38,12.9,15.1,0,14.9-11,38-11,29.4,0,25.9,28.5,61.9,28.5s40.1-39.9,79.8-39.9c33,0,38.7,18,63,18s32.9-15.9,49.9-15.9c13.1,0,19.7,4,26.3,9.6V32.7C835.5,27.1,828.8,19.7,815.8,19.7Z" />
</clipPath>
</svg>
Resources:
https://www.w3.org/TR/SVG11/masking.html#ClipPathElementClipPathUnitsAttribute
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/clipPathUnits
https://www.sarasoueidan.com/blog/css-svg-clipping/
When using clipPathUnits="objectBoundingBox" the width and height of the object bounding box of the clipping path are considered to have a length of 1 unit value.
In order to achieve this you either need to rewrite the d attribute of the path or you can scale the path. In this case I use transform="scale(0.00118,0.0017)"
<clipPath id="wav" clipPathUnits="objectBoundingBox">
<path transform="scale(0.00118,0.0017)" id="thePath" d="M815.8,19.7c-18.9,0-18.7,15.3-37.9,15.3-17.....
In order to know what value to use
I get the bounding box of the path:
let bb=thePath.getBBox();
I use the bb.width and bb.height to get the scale:
let sx = 1/bb.width;
let sy = 1/bb.height
I scale the path:
thePath.setAttribute("transform", scale(${sx},${sy}))
body {
background: #333;
}
#hero {
background: url(https://source.unsplash.com/random);
height: 120vh;
background-color: #ff0000;
width: 100vw;
background-size: cover;
clip-path: url(#wav);
}
#hero2 {
background: url(https://source.unsplash.com/random);
height: 120vh;
background-color: #ff0000;
width: 100vw;
background-size: cover;
clip-path: url(#wav2);
}
<div id="hero"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<clipPath id="wav" clipPathUnits="objectBoundingBox">
<path transform="scale(0.00118,0.0017)" id="thePath" d="M815.8,19.7c-18.9,0-18.7,15.3-37.9,15.3-17.6,0-19.6-13-38-13-15,0-14.9,11.1-38,11.1C672.5,33.1,676,4.6,640,4.6s-40.1,39.9-79.8,39.9c-33,0-38.7-18-63-18s-32.8,15.9-49.9,15.9c-13.1,0-19.7-4-26.3-9.7h0c-6.5-5.6-13.2-13-26.3-13C375.8,19.7,376,35,356.9,35c-17.6,0-19.7-13-38-13-15.1,0-14.9,11.1-38,11.1C251.5,33.1,255,4.6,219,4.6s-40.1,39.9-79.8,39.9c-33,0-38.7-18-63-18S43.3,42.4,26.3,42.4c-13.1,0-19.7-4-26.3-9.7V562.6c6.5,5.6,13.2,12.9,26.2,12.9,18.9,0,18.7-15.2,37.9-15.2,17.6,0,19.6,12.9,38,12.9,15,0,14.9-11,38-11,29.4,0,25.9,28.5,61.9,28.5s40.1-39.9,79.8-39.9c33,0,38.7,18,63,18s32.8-15.9,49.9-15.9c13.1,0,19.7,4,26.3,9.6h0c6.5,5.7,13.2,13,26.3,13,18.9,0,18.7-15.2,37.8-15.2,17.6,0,19.7,12.9,38,12.9,15.1,0,14.9-11,38-11,29.4,0,25.9,28.5,61.9,28.5s40.1-39.9,79.8-39.9c33,0,38.7,18,63,18s32.9-15.9,49.9-15.9c13.1,0,19.7,4,26.3,9.6V32.7C835.5,27.1,828.8,19.7,815.8,19.7Z" />
</clipPath>
</svg>
<div id="hero2"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<clipPath id="wav2" clipPathUnits="objectBoundingBox">
<path d="M815.8,19.7c-18.9,0-18.7,15.3-37.9,15.3-17.6,0-19.6-13-38-13-15,0-14.9,11.1-38,11.1C672.5,33.1,676,4.6,640,4.6s-40.1,39.9-79.8,39.9c-33,0-38.7-18-63-18s-32.8,15.9-49.9,15.9c-13.1,0-19.7-4-26.3-9.7h0c-6.5-5.6-13.2-13-26.3-13C375.8,19.7,376,35,356.9,35c-17.6,0-19.7-13-38-13-15.1,0-14.9,11.1-38,11.1C251.5,33.1,255,4.6,219,4.6s-40.1,39.9-79.8,39.9c-33,0-38.7-18-63-18S43.3,42.4,26.3,42.4c-13.1,0-19.7-4-26.3-9.7V562.6c6.5,5.6,13.2,12.9,26.2,12.9,18.9,0,18.7-15.2,37.9-15.2,17.6,0,19.6,12.9,38,12.9,15,0,14.9-11,38-11,29.4,0,25.9,28.5,61.9,28.5s40.1-39.9,79.8-39.9c33,0,38.7,18,63,18s32.8-15.9,49.9-15.9c13.1,0,19.7,4,26.3,9.6h0c6.5,5.7,13.2,13,26.3,13,18.9,0,18.7-15.2,37.8-15.2,17.6,0,19.7,12.9,38,12.9,15.1,0,14.9-11,38-11,29.4,0,25.9,28.5,61.9,28.5s40.1-39.9,79.8-39.9c33,0,38.7,18,63,18s32.9-15.9,49.9-15.9c13.1,0,19.7,4,26.3,9.6V32.7C835.5,27.1,828.8,19.7,815.8,19.7Z" />
</clipPath>
</svg>
This is from Sara Soueidan's article:
when you use the objectBoundingBox value, the coordinates specified for the contents of the <clipPath> must be in the range [0, 1]
And this is from MDN:
objectBoundingBox
This value indicates that all coordinates inside the element are relative to the bounding box of the element the clipping path is applied to. It means that the origin of the coordinate system is the top left corner of the object bounding box and the width and height of the object bounding box are considered to have a length of 1 unit value.

SVG styling problems with <use>

I'm trying to change, with CSS, the size and color of an SVG element that's being rendered with <use>. The SVG in question:
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
<path fill="#000000" fill-rule="evenodd" d="<all the actual svg path info>" clip-rule="evenodd"/>
</svg>
I do not have permission to change the contents of the SVG itself.
The way I'm using the SVG:
<svg>
<use xlink:href="#myIcon"></use>
</svg>
I've fought with this for hours, read through a pretty comprehensive article on the subject, and I still haven't had any success. I've tried applying classes to both the use element and the outer svg element, as well as referencing the path element inside. I can't seem to do anything to override the provided styles. How can I change the width, height, and fill color with this arrangement?
For the size it's easy if you correctly set the viewBox and then you adjust the width/height.
For the coloration you can rely on blending mode since the color of the SVG is black.
.icon {
display: inline-block;
background: #fff;
position: relative;
}
.icon::after {
content:"";
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
background:var(--c);
mix-blend-mode:lighten;
}
.icon>svg {
display: block;
}
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
<symbol id="myIcon">
<path fill="#000" d="M81,40.933c0-4.25-3-7.811-6.996-8.673c-0.922-5.312-3.588-10.178-7.623-13.844 c-2.459-2.239-5.326-3.913-8.408-4.981c-0.797-3.676-4.066-6.437-7.979-6.437c-3.908,0-7.184,2.764-7.979,6.442 c-3.078,1.065-5.939,2.741-8.396,4.977c-4.035,3.666-6.701,8.531-7.623,13.844C22.002,33.123,19,36.682,19,40.933 c0,2.617,1.145,4.965,2.957,6.589c0.047,0.195,0.119,0.389,0.225,0.568l26.004,43.873c0.383,0.646,1.072,1.04,1.824,1.04 c0.748,0,1.439-0.395,1.824-1.04L77.82,48.089c0.105-0.179,0.178-0.373,0.225-0.568C79.855,45.897,81,43.549,81,40.933z M49.994,11.235c2.164,0,3.928,1.762,3.928,3.93c0,2.165-1.764,3.929-3.928,3.929s-3.928-1.764-3.928-3.929 C46.066,12.997,47.83,11.235,49.994,11.235z M27.842,36.301c0.014,0,0.027,0,0.031,0c1.086,0,1.998-0.817,2.115-1.907 c0.762-7.592,5.641-13.791,12.303-16.535c1.119,3.184,4.146,5.475,7.703,5.475c3.561,0,6.588-2.293,7.707-5.48 c6.664,2.742,11.547,8.944,12.312,16.54c0.115,1.092,1.037,1.929,2.143,1.907c2.541,0.013,4.604,2.087,4.604,4.631 c0,1.684-0.914,3.148-2.266,3.958H25.508c-1.354-0.809-2.268-2.273-2.268-3.958C23.24,38.389,25.303,36.316,27.842,36.301z M50.01,86.723L27.73,49.13h44.541L50.01,86.723z" fill-rule="evenodd" clip-rule="evenodd"/>
</symbol>
</svg>
<!-- your code -->
<div class="icon" style="--c:red;">
<svg viewBox="0 0 100 125" width="100">
<use xlink:href="#myIcon"></use>
</svg>
</div>
<div class="icon" style="--c:green;">
<svg viewBox="0 0 100 125" width="150">
<use xlink:href="#myIcon"></use>
</svg>
</div>
<div class="icon" style="--c:blue;">
<svg viewBox="0 0 100 125" width="200">
<use xlink:href="#myIcon"></use>
</svg>
</div>
Save svg as a image with svg format then add the color and width or whatever you want to your img then add this to the html file as a img tag and display: none the svg code.
If you can't reach the html code then you can't do anything.

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

Responsive clip-path with inline SVG

On an element with a background (image or solid color don't really matter):
<header id="block-header"></header>
I am trying to apply a clip-path using SVG. To achieve this, I am putting SVG inline into the same element like this:
<header id="block-header">
…
<svg width="100%" height="100%" viewBox="0 0 4000 1696" preserveAspectRatio="none">
<defs>
<clipPath id="myClip">
<path d="M0 1568.18V0h4000v1568.18S3206.25 1696 2000 1696C984.37 1696 0 1568.18 0 1568.18z"/>
</clipPath>
</defs>
</svg>
…
</header>
You can run the code snippet below or check the JSFiddle. You can see original SVG image (in black) put inline, having curviness along the bottom and being responsive. In contrast, the red rectangle shows the same image applied (or, rather, not applied) as a clip-path.
I guess I misunderstand either viewBox or preserveAspectRatio attributes though can not find what is exactly wrong here. Any help would be appreciated.
#block-header {
background: Red;
min-height: 100px;
-webkit-clip-path: url(#myClip);
clip-path: url(#myClip);
}
<h1>SVG image</h1>
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100" viewBox="0 0 4000 1696" preserveAspectRatio="none"><path d="M0 1568.18V0h4000v1568.18S3206.25 1696 2000 1696C984.37 1696 0 1568.18 0 1568.18z"/></svg>
<h1><code>clip-path</code> using the same SVG</h1>
<header id="block-header">
<svg width="100%" height="100" viewBox="0 0 4000 1696" preserveAspectRatio="none">
<defs>
<clipPath id="myClip">
<path d="M0 1568.18V0h4000v1568.18S3206.25 1696 2000 1696C984.37 1696 0 1568.18 0 1568.18z"/>
</clipPath>
</defs>
</svg>
</header>
References to SVG clip paths are to the clip path definitions themselves and the dimensions or other attributes of the <svg> are meaningless in this context.
What is happening in your example is that you are applying a 4000 px wide clip path to your header. Which is probably only of the order of 900 px wide. So the curvature isn't visible.
If you want a responsive clip path, you should define it using clipPathUnits="objectBoundingBox".
#block-header {
background: Red;
min-height: 100px;
-webkit-clip-path: url(#myClip);
clip-path: url(#myClip);
}
<h1>SVG image</h1>
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100" viewBox="0 0 1 1" preserveAspectRatio="none"><path d="M0,0 1,0 1,0.9 C 1,0.9, 0.77,1, 0.5,1 0.23,1, 0,0.9,0,0.9z"/></svg>
<h1><code>clip-path</code> using the same SVG</h1>
<header id="block-header">
<svg width="0" height="0">
<defs>
<clipPath id="myClip" clipPathUnits="objectBoundingBox">
<path d="M0,0 1,0 1,0.9 C 1,0.9, 0.77,1, 0.5,1 0.23,1, 0,0.9,0,0.9z"/>
</clipPath>
</defs>
</svg>
</header>
Fiddle here

Resources