How to make right arc in a circle using SVG? - html

I am trying to make an arc like cut at the right of svg circle.
Current Result:
.ant-avatar-group {
display: inline-flex;
}
.ant-avatar {
width: 38px;
height: 38px;
line-height: 38px;
font-size: 19px;
background: #ccc;
border-radius: 50%;
}
<div class="ant-avatar-group">
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle opacity="0.15" cx="20" cy="20" r="19" fill="#F6BB43" stroke="white" stroke-width="2">
</circle>
</svg>
<span class="ant-avatar"> </span>
</div>
Expected Result:
Code Tried:
Changed, cx="20" to cx="30"
Also adding,
margin-left: -8px; and border-left: 4px solid #fff to .ant-avatar makes the avatar icon to distort (loose its original size) of the right avatar circle.
.ant-avatar-group {
display: inline-flex;
}
.ant-avatar {
width: 38px;
height: 38px;
line-height: 38px;
font-size: 19px;
background: #ccc;
border-radius: 50%;
}
<div class="ant-avatar-group">
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle opacity="0.15" cx="30" cy="20" r="19" fill="#F6BB43" stroke="white" stroke-width="2">
</circle>
</svg>
<span class="ant-avatar"> </span>
</div>
But this doesn't give the expected output as there needs to be arc like cut. Kindly help me to achieve the result making the svg circle with right arc as like the given expected result.
Big thanks in advance.

As I've commented I would put both circles in svg. For the image you can use clipPath to cut it in a circle shape.
For the other circle I'm usinga mask so that you can see through, since the mask is cutting a circular hole in it.
In CSS I've added a background to the svg. You can remove it
svg{width:300px; background:#efefef}
<svg viewBox="0 0 60 40">
<defs>
<mask id="m">
<rect fill="white" x="0" y="0" width="100" height="40" />
<circle cx="40" cy="20" r="18" fill="blabk" />
</mask>
<clipPath id="clip">
<circle cx="40" cy="20" r="16" fill="00f" />
</clipPath>
</defs>
<circle opacity="1" cx="20" cy="20" r="16" fill="#F6BB43" mask="url(#m)" />
<image href="https://assets.codepen.io/222579/darwin300.jpg" x="21" y="2" width="35" height="35" clip-path="url(#clip)" />
</svg>

Taking enxanetas'answer
Problem with inline SVGs is the ID values need to be unique per SVG,
or any following SVG will use the first defined mask/clip-path IDs
You can create those IDs dynamically:
svg {
width: 250px;
background: #efefef
}
<svg-avatar fill="#4267B2" href="https://i.imgur.com/iCKbSvQ.png"></svg-avatar>
<svg-avatar href="https://i.imgur.com/zTUDE6c.png"></svg-avatar>
<script>
customElements.define("svg-avatar", class extends HTMLElement {
connectedCallback() {
let id = n => n + Math.random() * 1e18; // create a unique id
let maskid = id("mask");
let clipid = id("clip");
this.innerHTML =
`<svg viewBox="0 0 60 40">
<defs>
<mask id="${maskid}"><rect fill="white"x="0"y="0"width="100"height="40"/><circle cx="40"cy="20"r="18"/></mask>
<clipPath id="${clipid}"><circle cx="40"cy="20"r="16"fill="00f"/></clipPath>
</defs>
<circle mask="url(#${maskid})"fill="${this.getAttribute("fill")||"#F6BB43"}"opacity="1"cx="20"cy="20"r="16"/>
<image href="${this.getAttribute("href")}"clip-path="url(#${clipid})"x="21"y="2"width="35"height="35"/>
</svg>`
}});
</script>

If you don't like the alternative you could just add another white circle that overlaps the existing one.... look here
<div class="ant-avatar-group">
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle opacity="0.15" cx="20" cy="20" r="19" fill="#F6BB43" stroke="white" stroke-width="2">
</circle>
<circle opacity="1" cx="47" cy="20" r="19" fill="#FFFFFF" stroke="white" stroke-width="2">
</circle>
</svg>
<span class="ant-avatar"> </span>
</div>
That will generate the arc but you still to set the negative margin-left to .ant-avatar to overlap the svg...

.ant-avatar-group {
display: inline-flex;
position:relative;
}
.ant-avatar {
position:absolute;
left:25px;
width: 38px;
height: 38px;
line-height: 38px;
font-size: 19px;
background: #ccc;
border:3px solid white;
border-radius: 50%;
}
<div class="ant-avatar-group">
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle opacity="0.15" cx="20" cy="20" r="19" fill="#F6BB43" stroke="white" stroke-width="2">
</circle>
</svg>
<span class="ant-avatar"> </span>
</div>

circle in svg should have cx="20" because the circle can't go out of it's parent... you should overlap the .ant-avatar over the svg using something like
.ant-avatar {
margin-left: -10px;
}

Related

SVG mask doesn't hide the elements in Chrome & Edge

For the life of me, I cannot figure out the issue with the inside the following SVGs:
https://codepen.io/LookyRo/pen/wvjezPE
.svgs-container {
display: flex;
gap: 10px;
text-align: center;
width: 100%;
}
.svgs-container div {
border: 2px solid red;
flex: 1 1 auto;
}
svg {
width: 250px;
}
<div class="svgs-container">
<div>
<h1>Mask BAD</h1>
<svg id="eI1EGNfkb8r1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 300 300" shape-rendering="geometricPrecision" text-rendering="geometricPrecision"
style="background-color:#000">
<g transform="matrix(.984808 0.173648-.173648 0.984808-41.142952 21.499616)" mask="url(#eI1EGNfkb8r6)">
<g transform="translate(-.244181 1.646644)">
<path d="M107.295374,68.86121c-3.202847,15.480427-37.900356,59.25267-13.345196,66.725979s59.252668,9.074732,70.99644-3.736656s11.209963-46.441282-5.871887-46.441282-27.224199-4.804272-25.088968-24.021353-19.217082-30.960854-21.886121-19.75089s10.676157,18.149466-4.804268,27.224202Z"
transform="translate(-8.760641-5.488538)" fill="#5717d1" stroke="#3f5787" stroke-width="0.6"/>
<rect style="isolation:isolate" width="27.224199" height="154.804271" rx="0" ry="0"
transform="matrix(.866025 0.5-.5 0.866025 243.998411-43.500831)" fill="#d2dbed" stroke-width="0"/>
</g>
<mask id="eI1EGNfkb8r6" mask-type="luminance">
<path d="M107.295374,68.86121c-3.202847,15.480427-37.900356,59.25267-13.345196,66.725979s59.252668,9.074732,70.99644-3.736656s11.209963-46.441282-5.871887-46.441282-27.224199-4.804272-25.088968-24.021353-19.217082-30.960854-21.886121-19.75089s10.676157,18.149466-4.804268,27.224202Z"
transform="matrix(-.865792 1.16328-.884732-.658478 328.565567-28.974333)" fill="#e34242"
stroke-width="0.6"/>
</mask>
</g>
</svg>
</div>
<div>
<h1>Mask GOOD</h1>
<svg id="em67u90McsE1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 300 300" shape-rendering="geometricPrecision" text-rendering="geometricPrecision"
style="background-color:#000">
<g transform="matrix(.984808 0.173648-.173648 0.984808-41.142952 21.499616)" mask="url(#em67u90McsE6)">
<g transform="translate(-.244181 1.646644)">
<path d="M107.295374,68.86121c-3.202847,15.480427-37.900356,59.25267-13.345196,66.725979s59.252668,9.074732,70.99644-3.736656s11.209963-46.441282-5.871887-46.441282-27.224199-4.804272-25.088968-24.021353-19.217082-30.960854-21.886121-19.75089s10.676157,18.149466-4.804268,27.224202Z"
transform="translate(-8.760641-5.488538)" fill="#5717d1" stroke="#3f5787" stroke-width="0.6"/>
<rect style="isolation:isolate" width="27.224199" height="154.804271" rx="0" ry="0"
transform="matrix(.866025 0.5-.5 0.866025 243.013603-43.327183)" fill="#d2dbed" stroke-width="0"/>
</g>
<mask id="em67u90McsE6" mask-type="luminance">
<path d="M107.295374,68.86121c-3.202847,15.480427-37.900356,59.25267-13.345196,66.725979s59.252668,9.074732,70.99644-3.736656s11.209963-46.441282-5.871887-46.441282-27.224199-4.804272-25.088968-24.021353-19.217082-30.960854-21.886121-19.75089s10.676157,18.149466-4.804268,27.224202Z"
transform="matrix(-.865792 1.16328-.884732-.658478 328.565567-28.974333)" fill="#e34242"
stroke-width="0.6"/>
</mask>
</g>
</svg>
</div>
</div>
The left one renders the elements inside the masked group and slightly casts a shadow where the mask should be. The right one works correctly.
I am seeing this issue un Chrome & Edge, yet Firefox, Opera and Safari displays both of this the same.
The only difference between these 2 SVGs is that the element is slightly moved on the X axis.
Bad: matrix(.866025 0.5-.5 0.866025 243.998411-43.500831)
Good: matrix(.866025 0.5-.5 0.866025 243.013603-43.327183)
All the rest of the code is exactly the same.
Can anyone figure this out?

is this a svg stroke-width bug in chrome?

Im trying to create a svg dot that i can scale up using stroke width.
I want to controll all my icons stroke-width with a variable and to do this i need to be able to create dots not just lines, but im getting some weird results when i have a small circle or a circular path and i increase the stroke width.
The red color is the circle fill, the blue color is the stroke but when increasing the stroke width im getting a gap between the fill and the stroke for some reason. (i used zoom 2000% to make everything bigger)
svg{
zoom: 3000%;
margin-top: 1px;
fill: red;
stroke: blue;
}
body{
display: flex;
div{
display: flex;
flex: 1;
align-items: center;
flex-direction: column;
height: 100%;
padding: 20px 0;
}
}
<div>
stroke-width: 1px;
<svg stroke-width="1" xmlns="http://www.w3.org/2000/svg" width="4" height="6.843" viewBox="0 0 4 6.843">
<g id="Group_614" data-name="Group 614" transform="translate(-851.372 -396.657)">
<path id="Group_608" data-name="Group 608" d="M16,22.1a.371.371,0,1,1-.371.371h0A.371.371,0,0,1,16,22.1Z" transform="translate(837.372 375.561)" stroke-miterlimit="10"/>
<circle id="Ellipse_20" data-name="Ellipse 20" cx="0.5" cy="0.5" r="0.5" transform="translate(852.872 401)" />
</g>
</svg>
</div>
<div>
stroke-width: 2px;
<svg stroke-width="2" xmlns="http://www.w3.org/2000/svg" width="4" height="6.843" viewBox="0 0 4 6.843">
<g id="Group_614" data-name="Group 614" transform="translate(-851.372 -396.657)">
<path id="Group_608" data-name="Group 608" d="M16,22.1a.371.371,0,1,1-.371.371h0A.371.371,0,0,1,16,22.1Z" transform="translate(837.372 375.561)" stroke-miterlimit="10"/>
<circle id="Ellipse_20" data-name="Ellipse 20" cx="0.5" cy="0.5" r="0.5" transform="translate(852.872 401)" />
</g>
</svg>
</div>
<div>
stroke-width: 3px;
<svg stroke-width="3px" xmlns="http://www.w3.org/2000/svg" width="4" height="6.843" viewBox="0 0 4 6.843">
<g id="Group_614" data-name="Group 614" transform="translate(-851.372 -396.657)">
<path id="Group_608" data-name="Group 608" d="M16,22.1a.371.371,0,1,1-.371.371h0A.371.371,0,0,1,16,22.1Z" transform="translate(837.372 375.561)" stroke-miterlimit="10"/>
<circle id="Ellipse_20" data-name="Ellipse 20" cx="0.5" cy="0.5" r="0.5" transform="translate(852.872 401)" />
</g>
</svg>
</div>
<div>
stroke-width: 4px;
<svg stroke-width="4px" xmlns="http://www.w3.org/2000/svg" width="4" height="6.843" viewBox="0 0 4 6.843">
<g id="Group_614" data-name="Group 614" transform="translate(-851.372 -396.657)">
<path id="Group_608" data-name="Group 608" d="M16,22.1a.371.371,0,1,1-.371.371h0A.371.371,0,0,1,16,22.1Z" transform="translate(837.372 375.561)" stroke-miterlimit="10"/>
<circle id="Ellipse_20" data-name="Ellipse 20" cx="0.5" cy="0.5" r="0.5" transform="translate(852.872 401)" />
</g>
</svg>
</div>
Trying to draw circles whose stroke is more than double the radius is not a good idea. As you have found, the behaviour in that situation is unreliable, and many 2D rendering libraries don't handle it gracefully. The correct behaviour isn't defined in the SVG spec either.
However, there is a simple solution to your problem. Simply draw a zero length line that has round end caps. The good news is that this is not a trick. It is safe to do because this behaviour is specified in the spec. And all SVG renderers handle it correctly.
svg{
margin-top: 1px;
fill: none;
stroke: blue;
stroke-linecap: round;
}
body{
display: flex;
div{
display: flex;
flex: 1;
align-items: center;
flex-direction: column;
height: 100%;
padding: 20px 0;
}
}
<div>
stroke-width: 1px;
<svg stroke-width="1" width="120" height="120" viewBox="0 0 4 4">
<path d="M2,2h0"/>
</svg>
</div>
<div>
stroke-width: 2px;
<svg stroke-width="2" width="120" height="120" viewBox="0 0 4 4">
<path d="M2,2h0"/>
</svg>
</div>
<div>
stroke-width: 3px;
<svg stroke-width="3" width="120" height="120" viewBox="0 0 4 4">
<path d="M2,2h0"/>
</svg>
</div>
<div>
stroke-width: 4px;
<svg stroke-width="4" width="120" height="120" viewBox="0 0 4 4">
<path d="M2,2h0"/>
</svg>
</div>

Scale SVG image non-proportionally to fit in remaining space

Below arrow is composed out of 3 single elements. The center part should stretch horizontally so the arrow can fill its surrounding container. But as you can see in the rendered code, the stretching doesn't work. How to enable stretching and making sure, there are no gaps at the junctures. Probably, there should be a small overlap between the parts because of the antialiasing (which is mandatory).
EDIT: Using preserveAspectRatio="none" suggested by #Turnip is stretching the image, but it is producing gaps and jumps on certain widths. See this screenshot:
Can't explain this weird behavior at all!
.arrow {
display: flex;
max-width: 200px;
padding-bottom: 2em;
}
.arrow svg {
height: 25px;
shape-rendering: auto;
}
#arrow-1 svg.stretched {}
#arrow-2 svg.stretched {
width: 100%;
}
<div class="arrow" id="arrow-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 25">
<path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M13 2.5h-1.31A5.21 5.21 0 006.5 7.69v14.62"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" class="mid" viewBox="0 0 3 25"><rect y="1" width="3" height="3"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 25">
<path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M5.5 15.84V7.69A5.21 5.21 0 00.31 2.5H0"/>
<path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z"/>
</svg>
</div>
<div class="arrow" id="arrow-2">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 25">
<path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M13 2.5h-1.31A5.21 5.21 0 006.5 7.69v14.62"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" class="stretched" viewBox="0 0 3 25"><rect y="1" width="3" height="3"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 25">
<path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M5.5 15.84V7.69A5.21 5.21 0 00.31 2.5H0"/>
<path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z"/>
</svg>
</div>
You can do the biggest part using CSS and it would easier to handle:
.box {
width: 50%;
margin: auto;
height: 50px;
border: 10px solid;
border-bottom: 0;
border-radius: 20px 20px 0 0;
position: relative;
}
.box::after {
content: "";
position: absolute;
bottom: 0;
right: -5px;
width: 45px;
height: 58px;
transform: translate(50%, 30%);
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 12 11 13"><path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z"></path></svg>') bottom/contain no-repeat;
}
<div class="box"></div>
Also like below:
.box {
width: 50%;
margin: auto;
height: 50px;
border: 10px solid;
border-bottom: 0;
border-radius: 20px 20px 0 0;
position: relative;
}
.box svg {
position: absolute;
bottom: 0;
right: -5px;
width: 45px;
transform: translate(50%, 30%);
}
<div class="box">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 12 11 13"><path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z"></path></svg>
</div>
Instead of using 3 svg elements I'm using only one. I'm putting the start and the end of the "arrow" in a <symbol> element so that I can use those shapes where I need them. Please observe that the <symbol> elements have a tight viewbox (the viewBox is wrapping tight the shape and has the same size as the bounding box of the shape + some extra space for the 1/2 width of the line).
Now I can use those symbols as many times as I need and where I need.
In order to connect the 2 use elements I'm using a line. please observe that the x1 attribute of the line (in the first group) is 18 where 18 = 10 (the x attribute of the first use element) + 8 (the width attribute of the first use element).
The x2 attribute of the line deppends on how long you need it to be and has the same value as the attribute x of the second use element.
<svg viewBox="0 0 130 70">
<symbol id="start" xmlns="http://www.w3.org/2000/svg" viewBox="5 0 8 22">
<path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M13 2.5h-1.31A5.21 5.21 0 006.5 7.69v14.62" />
</symbol>
<symbol id="end" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 25">
<path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M5.5 15.84V7.69A5.21 5.21 0 00.31 2.5H0" />
<path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z" />
</symbol>
<g id="g1">
<use xlink:href="#start" x="10" width="8" height="22" />
<use xlink:href="#end" x="100" width="11" height="25" />
<line x1="18" y1="2.5" x2="100" y2="2.5" stroke="black" stroke-width="3" stroke-linecap="round" />
</g>
<g id="g2">
<use xlink:href="#start" x="20" y="35" width="8" height="22" />
<use xlink:href="#end" x="70" y="35" width="11" height="25" />
<line x1="28" x2="70" y1="37.5" y2="37.5" stroke="black" stroke-width="3" stroke-linecap="round" />
</g>
</svg>
Use preserveAspectRatio="none" on the SVG that you want to stretch. This will allow the inner rect to stretch along with the SVG element.
.arrow {
display: flex;
max-width: 200px;
padding-bottom: 2em;
}
.arrow svg {
height: 25px;
shape-rendering: auto;
}
#arrow-1 svg.stretched {}
#arrow-2 svg.stretched {
width: 100%;
}
<div class="arrow" id="arrow-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 25">
<path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M13 2.5h-1.31A5.21 5.21 0 006.5 7.69v14.62"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" class="mid" viewBox="0 0 3 25"><rect y="1" width="3" height="3"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 25">
<path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M5.5 15.84V7.69A5.21 5.21 0 00.31 2.5H0"/>
<path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z"/>
</svg>
</div>
<div class="arrow" id="arrow-2">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 25">
<path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M13 2.5h-1.31A5.21 5.21 0 006.5 7.69v14.62"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" class="stretched" viewBox="0 0 3 25" preserveAspectRatio="none"><rect y="2" width="3" height="3"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 25">
<path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="3" d="M5.5 15.84V7.69A5.21 5.21 0 00.31 2.5H0"/>
<path d="M5.5 24.31l4.88-11.94-4.88 2.84-4.88-2.84L5.5 24.31z"/>
</svg>
</div>

Change SVG fill="none" to fill="#FFF" when Hover?

This SVG have 2 fill one is NONE and secound is color RED.
How I do so when it's not hover one stay in NONE, then when it's hover it change to color?
By the way it's right now, it only change the one that is red of the
.icon{
fill: red;
transition: all 200ms ease-out;
}
.icon:hover{
fill: blue;
}
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="22" viewBox="0 0 24 22">
<path fill="none" d="M17.73,3c-3.26,0-5,3.47-5.73,5-.75-1.54-2.48-5-5.72-5A4.05,4.05,0,0,0,2,7.19c0,3.44,4.74,7.85,10,13,5.26-5.15,10-9.56,10-13A4.06,4.06,0,0,0,17.73,3Z" transform="translate(0 -1)" />
<path fill="#ff0000" d="M17.73,1A6.53,6.53,0,0,0,12,4.25,6.51,6.51,0,0,0,6.28,1,6,6,0,0,0,0,7.19C0,11.85,5.57,16.62,12,23c6.43-6.38,12-11.15,12-15.81A6,6,0,0,0,17.73,1ZM12,20.19C6.74,15,2,10.63,2,7.19A4.05,4.05,0,0,1,6.28,3c3.24,0,5,3.49,5.72,5,.75-1.55,2.47-5,5.73-5A4.06,4.06,0,0,1,22,7.19C22,10.63,17.26,15,12,20.19Z" transform="translate(0 -1)"/>
</svg>
Try adding a wrapper class and giving css fill to the svg path. This is a sample code. Hope it helps
.svg-wrapper svg path{
fill: red;
transition: all 200ms ease-out;
}
.svg-wrapper svg path:hover{
fill: blue;
}
<div class="svg-wrapper">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="22" viewBox="0 0 24 22">
<path fill="none" d="M17.73,3c-3.26,0-5,3.47-5.73,5-.75-1.54-2.48-5-5.72-5A4.05,4.05,0,0,0,2,7.19c0,3.44,4.74,7.85,10,13,5.26-5.15,10-9.56,10-13A4.06,4.06,0,0,0,17.73,3Z" transform="translate(0 -1)" />
<path fill="#ff0000" d="M17.73,1A6.53,6.53,0,0,0,12,4.25,6.51,6.51,0,0,0,6.28,1,6,6,0,0,0,0,7.19C0,11.85,5.57,16.62,12,23c6.43-6.38,12-11.15,12-15.81A6,6,0,0,0,17.73,1ZM12,20.19C6.74,15,2,10.63,2,7.19A4.05,4.05,0,0,1,6.28,3c3.24,0,5,3.49,5.72,5,.75-1.55,2.47-5,5.73-5A4.06,4.06,0,0,1,22,7.19C22,10.63,17.26,15,12,20.19Z" transform="translate(0 -1)"/>
</svg>
</div>
You can animate it with an SVG tag. Here is how you would animate the fill property back and forth with an hover effect on a square:
<?xml version="1.0"?>
<svg width="120" height="120" viewBox="0 0 120 120" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="10" width="100" height="100" fill='#000000'>
<animate attributeType="XML" attributeName="fill" from="#000000" to="#ff0000"
dur="0.5s" repeatCount="1" begin='mouseover' fill='freeze'/>
<animate attributeType="XML" attributeName="fill" from="#ff0000" to="#000000"
dur="0.5s" repeatCount="1" begin='mouseout' fill='freeze'/>
</rect>
</svg>
When this SVG is placed on a page it will turn red when you rollover it and go back to black when rolling out.

wavy button shape with text inside

I'm trying to create this button:
I'm doing this with SVG, so here is my code:
.svg-button {
position:relative;
}
a.test {
display:block;
}
<div class="svg-button">
<?xml version="1.0" encoding="UTF-8"?>
<svg width="150px" height="51px" viewBox="0 0 150 51" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Desktop-HD" transform="translate(-987.000000, -779.000000)" stroke="#102CCA">
<g id="Group-6" transform="translate(836.000000, 668.000000)">
<g id="Group" transform="translate(151.000000, 111.000000)">
<path d="M0.5,0.5 L0.5,47.4475413 C38.7946588,43.6370428 73.268313,43.6553687 103.92161,47.5038947 C134.273898,51.314629 149.5,49.8747765 149.5,43.6367187 L149.5,30.078125 C149.5,19.2695184 149.5,19.0898429 149.5,0.936176488 L0.5,0.5 Z" id="Rectangle"></path>
</g>
</g>
</g>
</g>
</svg>
<a class="test" href="#">add to cart</a>
</div>
Any ideas on how I might integrate the text inside the shape and add a hover state for the shape/button?
Thanks!
There are a number of ways you could do it.
You could move the text into the SVG using a <text> element...
a.test:hover svg path {
fill: red;
}
<div class="svg-button">
<a class="test" href="#">
<svg width="150px" height="51px" viewBox="0 0 150 51" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Desktop-HD" transform="translate(-987.000000, -779.000000)" stroke="#102CCA">
<g id="Group-6" transform="translate(836.000000, 668.000000)">
<g id="Group" transform="translate(151.000000, 111.000000)">
<path d="M0.5,0.5 L0.5,47.4475413 C38.7946588,43.6370428 73.268313,43.6553687 103.92161,47.5038947 C134.273898,51.314629 149.5,49.8747765 149.5,43.6367187 L149.5,30.078125 C149.5,19.2695184 149.5,19.0898429 149.5,0.936176488 L0.5,0.5 Z" id="Rectangle"></path>
</g>
</g>
</g>
</g>
<text x="75" y="27" text-anchor="middle">add to cart</text>
</svg>
</a>
</div>
Or if you wanted to keep the text as HTML. You could use relative/absolute positioning to centre the text over the SVG.
.svg-button {
position: relative;
}
.svg-button svg,
.svg-button a {
position: absolute;
display: block;
width: 150px;
height: 51px;
top: 0;
}
.svg-button a {
text-align: center;
line-height: 45px;
}
.svg-button:hover svg path {
fill: red;
}
<div class="svg-button">
<svg width="150px" height="51px" viewBox="0 0 150 51" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Desktop-HD" transform="translate(-987.000000, -779.000000)" stroke="#102CCA">
<g id="Group-6" transform="translate(836.000000, 668.000000)">
<g id="Group" transform="translate(151.000000, 111.000000)">
<path d="M0.5,0.5 L0.5,47.4475413 C38.7946588,43.6370428 73.268313,43.6553687 103.92161,47.5038947 C134.273898,51.314629 149.5,49.8747765 149.5,43.6367187 L149.5,30.078125 C149.5,19.2695184 149.5,19.0898429 149.5,0.936176488 L0.5,0.5 Z" id="Rectangle"></path>
</g>
</g>
</g>
</g>
</svg>
<a class="test" href="#">add to cart</a>
</div>
I'd recommend grouping the svg path and the text 'add to cart' inside of the svg (with a "g" element). I'm also guessing that you want this whole button to act as the link, so I'd recommend structuring the HTML like the following:
<a>
<svg>
<g>
<path></path>
<text>Add to cart</text>
</g>
</svg>
</a>
...and positioning the path and the text inside of the group with x and y values. You can then target the path and the text, when the whole link is being hovered on like this:
a:hover svg g text {
fill: red;
}
a:hover svg g path {
stroke: red;
}
Check out this simple codepen I made for a demo and let me know if you have any questions! https://codepen.io/segheysens/pen/VzbzeJ