Clip-path is not working. Did I miss something? - css

I'm trying to use clip-path in CSS but it's not working. I've watched plenty tutorials by now and it seems simple, but it's just not working and doesn't appear to be trying to work. I should also mention I'm using React--which, whenever I've run into issues recently, it's caused by React.
To my own knowledge, I've done everything I'm supposed to. The SVG is loaded in the DOM as a clipPath tag, with a unique ID and I reference that ID in the CSS.
Please help. Thanks.
SVG Blob (imported in the DOM via import {ReactComponent as LIST_ICON} from ...:
<svg className="list-icon" viewBox="0 0 64 48">
<path d="M12.343,2V10.343c0,1.104-.896,2-2,2H2c-1.105,0-2-.896-2-2V2C0,.896,.895,0,2,0H10.343c1.104,0,2,.896,2,2Zm-2,15.829H2c-1.105,0-2,.896-2,2v8.343c0,1.104,.895,2,2,2H10.343c1.104,0,2-.896,2-2v-8.343c0-1.104-.896-2-2-2Zm0,17.829H2c-1.105,0-2,.896-2,2v8.343c0,1.105,.895,2,2,2H10.343c1.104,0,2-.895,2-2v-8.343c0-1.104-.896-2-2-2ZM62,0H19.828c-1.104,0-2,.896-2,2V10.343c0,1.104,.896,2,2,2H62c1.104,0,2-.896,2-2V2c0-1.104-.896-2-2-2Zm0,17.829H19.828c-1.104,0-2,.896-2,2v8.343c0,1.104,.896,2,2,2H62c1.104,0,2-.896,2-2v-8.343c0-1.104-.896-2-2-2Zm0,17.829H19.828c-1.104,0-2,.896-2,2v8.343c0,1.105,.896,2,2,2H62c1.104,0,2-.895,2-2v-8.343c0-1.104-.896-2-2-2Z" />
<symbol id="list-icon" viewBox="0 0 64 48">
<path d="M12.343,2V10.343c0,1.104-.896,2-2,2H2c-1.105,0-2-.896-2-2V2C0,.896,.895,0,2,0H10.343c1.104,0,2,.896,2,2Zm-2,15.829H2c-1.105,0-2,.896-2,2v8.343c0,1.104,.895,2,2,2H10.343c1.104,0,2-.896,2-2v-8.343c0-1.104-.896-2-2-2Zm0,17.829H2c-1.105,0-2,.896-2,2v8.343c0,1.105,.895,2,2,2H10.343c1.104,0,2-.895,2-2v-8.343c0-1.104-.896-2-2-2ZM62,0H19.828c-1.104,0-2,.896-2,2V10.343c0,1.104,.896,2,2,2H62c1.104,0,2-.896,2-2V2c0-1.104-.896-2-2-2Zm0,17.829H19.828c-1.104,0-2,.896-2,2v8.343c0,1.104,.896,2,2,2H62c1.104,0,2-.896,2-2v-8.343c0-1.104-.896-2-2-2Zm0,17.829H19.828c-1.104,0-2,.896-2,2v8.343c0,1.105,.896,2,2,2H62c1.104,0,2-.895,2-2v-8.343c0-1.104-.896-2-2-2Z" />
</symbol>
<defs>
<clipPath id="list-icon-clip" clipPathUnits="objectBoundingBox">
<path d="M12.343,2V10.343c0,1.104-.896,2-2,2H2c-1.105,0-2-.896-2-2V2C0,.896,.895,0,2,0H10.343c1.104,0,2,.896,2,2Zm-2,15.829H2c-1.105,0-2,.896-2,2v8.343c0,1.104,.895,2,2,2H10.343c1.104,0,2-.896,2-2v-8.343c0-1.104-.896-2-2-2Zm0,17.829H2c-1.105,0-2,.896-2,2v8.343c0,1.105,.895,2,2,2H10.343c1.104,0,2-.895,2-2v-8.343c0-1.104-.896-2-2-2ZM62,0H19.828c-1.104,0-2,.896-2,2V10.343c0,1.104,.896,2,2,2H62c1.104,0,2-.896,2-2V2c0-1.104-.896-2-2-2Zm0,17.829H19.828c-1.104,0-2,.896-2,2v8.343c0,1.104,.896,2,2,2H62c1.104,0,2-.896,2-2v-8.343c0-1.104-.896-2-2-2Zm0,17.829H19.828c-1.104,0-2,.896-2,2v8.343c0,1.105,.896,2,2,2H62c1.104,0,2-.895,2-2v-8.343c0-1.104-.896-2-2-2Z" />
</clipPath>
</defs>
</svg>
More specifically:
<defs>
<clipPath id="list-icon-clip" clipPathUnits="objectBoundingBox">
<path d="M12.343,2V10.343c0,1.104-.896,2-2,2H2c-1.105,0-2-.896-2-2V2C0,.896,.895,0,2,0H10.343c1.104,0,2,.896,2,2Zm-2,15.829H2c-1.105,0-2,.896-2,2v8.343c0,1.104,.895,2,2,2H10.343c1.104,0,2-.896,2-2v-8.343c0-1.104-.896-2-2-2Zm0,17.829H2c-1.105,0-2,.896-2,2v8.343c0,1.105,.895,2,2,2H10.343c1.104,0,2-.895,2-2v-8.343c0-1.104-.896-2-2-2ZM62,0H19.828c-1.104,0-2,.896-2,2V10.343c0,1.104,.896,2,2,2H62c1.104,0,2-.896,2-2V2c0-1.104-.896-2-2-2Zm0,17.829H19.828c-1.104,0-2,.896-2,2v8.343c0,1.104,.896,2,2,2H62c1.104,0,2-.896,2-2v-8.343c0-1.104-.896-2-2-2Zm0,17.829H19.828c-1.104,0-2,.896-2,2v8.343c0,1.105,.896,2,2,2H62c1.104,0,2-.895,2-2v-8.343c0-1.104-.896-2-2-2Z" />
</clipPath>
</defs>
JSX (HTML):
<button className="hint-cache-toggle" onClick={e => e.preventDefault()}>
CSS:
#answer-input .hint-cache-toggle {
position: absolute;
inset: auto 0 0 auto;
border: none;
width: 64px;
height: 48px;
clip-path: url("#list-icon-clip");
/* -webkit-clip-path: url("#list-icon-clip"); */
background-color: black;
}

Related

Any way to use SVG Sprite from CSS?

HTML:
<svg>
<use xlink:href="/assets/images/icons-sprite.svg#icon-name"></use>
</svg>
SVG sprite:
<svg width="0" height="0" class="hidden">
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="icon-name">
<path ... fill="currentColor"></path>
</symbol>
</svg>
Is there any way to use SVG sprite from CSS
Like this
<div class=“icon”></div>
.icon {
background-image: “/assets/images/icons-sprite.svg#icon-name”
height: 30px
}
I’m using the technique for including SVGs described here whereby you create a doc that looks something like this…
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="arrow-left" viewBox="0 0 10 16">
<path d="M9.4 1.4L8 0 0 8l8 8 1.4-1.4L2.8 8z"/>
</symbol>
<symbol id="arrow-right" viewBox="0 0 10 16">
<path d="M0 14.6L1.4 16l8-8-8-8L0 1.4 6.6 8z"/>
</symbol>
</svg>
Include it in the top of your HTML and then insert the SVG icons in your markup like this…
<svg class="arrow-right">
<use xlink:href="#arrow-right" />
</svg>
It’s easy and works great. However, I’m trying to use the same icons in my CSS pseudo classes :before and :after using an empty content attribute and the SVG in the background. Something like this…
.title:after {
float: right;
width: 16px;
height: 10px;
content: "";
background: url('#arrow-right');
}

How to position my svg image to the center of browser

I generated a simple svg image and loaded it to Chrome. Meant to position it to the center of browser(even when the browser resizing), but so far have failed on this.
Have referred to some articles about viewport/viewbox setting, and some Q&As on this site(https://stackoverflow.com/questions/8639383/how-do-i-center-an-svg-in-a-div;https://stackoverflow.com/questions/13373169/align-svg-to-center-of-screen), but haven't got it done. Maybe I missed something, since I am very new to this.
Here is the full code for this svg image:
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
width="100%"
height="100%"
viewBox="0 -700 1080 1920"
preserveAspectRatio="xMidYMid meet"
version="1.1"
id="mysvg"
>
<g
id="group" >
<circle
r="500"
style="fill:#ffb721;fill-opacity:1"
cy="0"
cx="0"
id="path" />
<circle
style="fill:#f71c17;fill-opacity:1;"
id="path2"
cx="0"
cy="0"
r="250" />
</g>
</svg>
I expect this image could stay at the center of the browser, even during browser resizing.
I think this is what you want?
The SVG will be position in the center even the browser resized and scroll
ON GLOBAL CSS
CSS:
#container {
top: 50%;
left: 50%;
position: fixed;
transform: translate(-50%, -50%);
}
INSIDE SVG
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 439.29 439.29" width="100%" height="100%">
<g id="group">
<circle cx="219.64" cy="219.64" r="219.64" style="fill: #ffb721" id="path"/>
<circle cx="219.64" cy="219.64" r="108.32" style="fill: #f71c17" id="path2"/>
</g>
</svg>
Your SVG needs a little modification to center it in the ViewBox.
body {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.container {
width: 300px;
height: 300px;
background-color: rgba(red, .3);
}
<div class="container">
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
width="100%"
height="100%"
viewBox="-540 -960 1080 1920"
preserveAspectRatio="xMidYMid meet"
version="1.1"
id="mysvg"
>
<g
id="group" >
<circle
r="500"
style="fill:#ffb721;fill-opacity:1"
cy="0"
cx="0"
id="path" />
<circle
style="fill:#f71c17;fill-opacity:1;"
id="path2"
cx="0"
cy="0"
r="250" />
</g>
</svg>
</div>

clipPath transform on :focus/:hover for multiple instances of same icon

I have an SVG icon with some masked shapes comprised of:
book-1: masked by clipPath mask-1
book-2: masked by clipPath mask-2
book-3: not masked, no transform required
On :focus / :hover I want mask-1 (but not book-1), and book-2 (but not mask-2) to transform. Straightforward enough…
<a href="whatevs" class="icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44 44">
<defs>
<style>
#book-1 {clip-path:url(#mask-1);}
#book-2 {clip-path:url(#mask-2);}
</style>
<clipPath id="mask-1">
<path class="nudge" fill="none" … />
</clipPath>
<clipPath id="mask-2">
<path fill="none" … />
</clipPath>
</defs>
<g id="book-1">
<path fill="#fff" … />
</g>
<g id="book-2">
<path fill="#fff" class="nudge" … />
</g>
<path fill="#fff" … /> <!-- book-3 -->
</svg>
</a>
/* CSS */
.icon .nudge {
transition: transform 0.2s ease-in;
}
.icon:focus .nudge,
.icon:hover .nudge {
transform: translate(-2px, 2px);
}
But the fun begins when there are multiple instances of the same icon in a page.
I have 3 Pens on CodePen, each with 2 instances of the linked icon, where:
MRYwBq fails with:
verbose code stating the full SVG each time it appears
class names for book-1 and book-2
unique id names for every instance of just the masks: mask-1 and mask-2
qwEZrG works with:
verbose code stating the full SVG each time it appears
unique id names for every instance of the books and the masks: book-1, mask-1, book-2 and mask-2
gybrvL fails with:
a <symbol> instance of the icon iterated via <use> in the page
Thoughts
This is just weird. I’d like to understand why it fails the way it does.
It’s good that this works but I would prefer not to have to iterate the IDs with JavaScript after they have been sent to the page undifferentiated.
This is what I’d like to get working, but I don’t know if that’s possible.
Since the clip-path requires an id of a svg def child, only one of these <clipPath> definitions will be taken into account in case multiple icons are placed on a page. That's why transforming the <clipPath> elements is a no-go, as all items referencing it will be affected. As a consequence, we need a solution that does not move or modify these elements based on :hover of :focus.
Fortunately, it is possible to move just the clipping path assigned to an element "without" moving the element itself by using the following trick:
Assign the clip path to the parent
Move the parent in the direction that the clip path should move
Move all children in the opposite direction
An example of this trick based on the code you provided can be found in the snippet below:
a .nudge, a .unnudge {
transition: transform 0.2s ease-in;
}
a:focus,
a:hover {
background-color: black;
}
a:focus .nudge,
a:hover .nudge {
transform: translate(-2px, 2px);
}
a:focus .unnudge,
a:hover .unnudge {
transform: translate(2px, -2px);
}
* {
box-sizing: border-box;
}
a {
display: block;
background-color: red;
padding: 0.5rem;
border-radius: 50%;
transition: background-color 0.2s ease-in;
width: 60px;
height: 60px;
}
body {
font-family: sans-serif;
line-height: 1.5;
max-width: 36em;
color: #333;
}
code {
background: #e5e5e5;
font-size: 1.125em;
border-radius: 2px;
}
<p>Instance 1:
<a href="#">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44 44" width="44" height="44">
<defs>
<style>
.book-1{clip-path:url(#mask-1-1);}
.book-2{clip-path:url(#mask-2-1);}
</style>
<clipPath id="mask-1-1">
<path fill="none" d="M13.823,33.1V18.293a4.738,4.738,0,0,1,1.4-3.371S24.6,5.531,25.085,5.048L20.019-.019H8.143V33.1Z"/>
</clipPath>
<clipPath id="mask-2-1">
<path fill="none" d="M31.814,10.117,21.12,20.822a4.733,4.733,0,0,0-1.4,3.371V39H12V7H28.7Z"/>
</clipPath>
</defs>
<g class="nudge book-1" >
<path fill="#fff" class="unnudge" d="M22.736,5.72a1.193,1.193,0,0,0-1.686,0l-7.516,7.516a1.191,1.191,0,0,1-1.685-1.685l7.516-7.516a1.192,1.192,0,0,0-1.686-1.686L10.163,9.865h0a3.565,3.565,0,0,0-1.047,2.529h0V26.625h0a3.576,3.576,0,0,0,6.1,2.528h0l7.516-7.516a1.188,1.188,0,0,0,.349-.843V6.563A1.188,1.188,0,0,0,22.736,5.72Z"/>
</g>
<g class="book-2">
<path fill="#fff" class="nudge" d="M21.723,22.193a4.733,4.733,0,0,1,1.4-3.371l5.865-5.871v-.488a1.192,1.192,0,0,0-2.035-.843l-7.516,7.516a1.192,1.192,0,0,1-1.686-1.686l7.516-7.516a1.191,1.191,0,1,0-1.685-1.685l-7.516,7.516a3.561,3.561,0,0,0-1.048,2.528h0V32.524h0a3.577,3.577,0,0,0,6.105,2.529h0l.6-.6Z"/>
</g>
<path fill="#fff" d="M34.535,17.52a1.19,1.19,0,0,0-1.685,0l-7.516,7.516a1.192,1.192,0,0,1-1.686-1.686l7.516-7.516a1.192,1.192,0,1,0-1.686-1.685l-7.516,7.516h0a3.564,3.564,0,0,0-1.047,2.528h0V38.424h0a3.576,3.576,0,0,0,6.1,2.529h0l7.516-7.516a1.188,1.188,0,0,0,.349-.843V18.363A1.188,1.188,0,0,0,34.535,17.52Z"/>
</svg>
</a>
</p>
<p>Instance 2, exact copy of instance 1:
<a href="#">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44 44" width="44" height="44">
<defs>
<style>
.book-1{clip-path:url(#mask-1-1);}
.book-2{clip-path:url(#mask-2-1);}
</style>
<clipPath id="mask-1-1">
<path fill="none" d="M13.823,33.1V18.293a4.738,4.738,0,0,1,1.4-3.371S24.6,5.531,25.085,5.048L20.019-.019H8.143V33.1Z"/>
</clipPath>
<clipPath id="mask-2-1">
<path fill="none" d="M31.814,10.117,21.12,20.822a4.733,4.733,0,0,0-1.4,3.371V39H12V7H28.7Z"/>
</clipPath>
</defs>
<g class="nudge book-1" >
<path fill="#fff" class="unnudge" d="M22.736,5.72a1.193,1.193,0,0,0-1.686,0l-7.516,7.516a1.191,1.191,0,0,1-1.685-1.685l7.516-7.516a1.192,1.192,0,0,0-1.686-1.686L10.163,9.865h0a3.565,3.565,0,0,0-1.047,2.529h0V26.625h0a3.576,3.576,0,0,0,6.1,2.528h0l7.516-7.516a1.188,1.188,0,0,0,.349-.843V6.563A1.188,1.188,0,0,0,22.736,5.72Z"/>
</g>
<g class="book-2">
<path fill="#fff" class="nudge" d="M21.723,22.193a4.733,4.733,0,0,1,1.4-3.371l5.865-5.871v-.488a1.192,1.192,0,0,0-2.035-.843l-7.516,7.516a1.192,1.192,0,0,1-1.686-1.686l7.516-7.516a1.191,1.191,0,1,0-1.685-1.685l-7.516,7.516a3.561,3.561,0,0,0-1.048,2.528h0V32.524h0a3.577,3.577,0,0,0,6.105,2.529h0l.6-.6Z"/>
</g>
<path fill="#fff" d="M34.535,17.52a1.19,1.19,0,0,0-1.685,0l-7.516,7.516a1.192,1.192,0,0,1-1.686-1.686l7.516-7.516a1.192,1.192,0,1,0-1.686-1.685l-7.516,7.516h0a3.564,3.564,0,0,0-1.047,2.528h0V38.424h0a3.576,3.576,0,0,0,6.1,2.529h0l7.516-7.516a1.188,1.188,0,0,0,.349-.843V18.363A1.188,1.188,0,0,0,34.535,17.52Z"/>
</svg>
</a>
</p>
Please note, that this solution is not perfect, and the trick with having two opposite movements that should sum up to no movement, can result in a bit of jerkiness of the .book-1 on some browsers (e.g. Firefox).

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

Resources