Remove stroke from one side of SVG using stroke-dasharray - html

I am wondering is there a way have border (or stroke) all around except on the right side of the star (maybe using stroke-dasharray)?
SVG:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" class="SvgDefinitions">
<defs>
<symbol id="HalfStar" viewBox="0 0 20 19">
<path d="M9,0.6L6.5,5.7L0.9,6.5c-0.2,0-0.4,0.1-0.6,0.3c-0.4,0.4-0.4,1,0,1.4l4.1,4l-1,5.6c0,0.2,0,0.4,0.1,0.6 c0.3,0.5,0.9,0.7,1.4,0.4l5.1-2.7l0,0V0C9.6,0,9.2,0.2,9,0.6z" />
</symbol>
</defs>
</svg>
<svg class="Star-Container">
<use href="#HalfStar" x-link:href="#HalfStar" />
</svg>
CSS:
#HalfStar {
stroke: red;
stroke-dasharray: 5,4;
}
CodePen: https://codepen.io/amir734jj/pen/zYqWZRN

The total length of the contour of half of the star measured with getTotalLength() is - 50px
The vertical bar length of the star is - 16px
For this segment, stroke-dasharray =" 0 16 " where 0 is the length of the stroke 16 is the length of the space
Therefore, the area of the star that should be filled with strokes is 34px
For 5 groups of strokes and spaces - 34/10 = 3,4px
As a result, the general formula will be:
stroke-dasharray="3.4,3.4 3.4,3.4 3.4,3.4 3.4,3.4 3.4,3.4 0, 16"
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" class="SvgDefinitions">
<defs>
<symbol id="HalfStar" viewBox="0 0 20 19">
<path stroke="red" stroke-dashoffset="0"
stroke-dasharray="3.4,3.4 3.4,3.4 3.4,3.4 3.4,3.4 3.4,3.4 0, 16"
d="M9,0.6L6.5,5.7L0.9,6.5c-0.2,0-0.4,0.1-0.6,0.3c-0.4,0.4-0.4,1,0,1.4l4.1,4l-1,5.6c0,0.2,0,0.4,0.1,0.6 c0.3,0.5,0.9,0.7,1.4,0.4l5.1-2.7l0,0V0C9.6,0,9.2,0.2,9,0.6z" />
</symbol>
</defs>
</svg>
<svg class="Star-Container">
<use href="#HalfStar" x-link:href="#HalfStar" />
</svg>
#NodeJS by comment
Is there a way for the border to be continuous for the rest and not
dashed?
To do this, swap 0, 16 by 16, 0 in the last group of parameters stroke-dasharray
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" class="SvgDefinitions">
<defs>
<symbol id="HalfStar" viewBox="0 0 20 19">
<path stroke="red" stroke-dashoffset="3"
stroke-dasharray="3.4,3.4 3.4,3.4 3.4,3.4 3.4,3.4 3.4,3.4 16,0"
d="M9,0.6L6.5,5.7L0.9,6.5c-0.2,0-0.4,0.1-0.6,0.3c-0.4,0.4-0.4,1,0,1.4l4.1,4l-1,5.6c0,0.2,0,0.4,0.1,0.6 c0.3,0.5,0.9,0.7,1.4,0.4l5.1-2.7l0,0V0C9.6,0,9.2,0.2,9,0.6z" />
</symbol>
</defs>
</svg>
<svg class="Star-Container">
<use href="#HalfStar" x-link:href="#HalfStar" />
</svg>
#Apha by comment
Your solution doesn't have a continuous border on the left. It's
dashed. I think the OP wanted continuous border on the left and no
border on the right
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" class="SvgDefinitions">
<defs>
<symbol id="HalfStar" viewBox="0 0 20 19">
<path stroke="red" stroke-dashoffset="0.75"
stroke-dasharray="33.5,0 0,16.5"
d="M9,0.6L6.5,5.7L0.9,6.5c-0.2,0-0.4,0.1-0.6,0.3c-0.4,0.4-0.4,1,0,1.4l4.1,4l-1,5.6c0,0.2,0,0.4,0.1,0.6 c0.3,0.5,0.9,0.7,1.4,0.4l5.1-2.7l0,0V0C9.6,0,9.2,0.2,9,0.6z" />
</symbol>
</defs>
</svg>
<svg class="Star-Container">
<use href="#HalfStar" x-link:href="#HalfStar" />
</svg>

Related

how to mask an svg shape to an svg image

So basically I have a triangular shape and I want to mask it in an image/gif.
<svg width="209" height="143" viewBox="0 0 209 143" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M104.5 0L0.143921 142.5H208.856L104.5 0ZM104.5 10.1551L11.9747 136.5H197.025L104.5 10.1551Z" fill="black"/>
</svg>
<div class="clipSvg2">
<svg viewBox="0 0 300 300" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<mask id="mask11">
<!-- <svg width="209" height="143" viewBox="0 0 209 143" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M104.5 0L0.143921 142.5H208.856L104.5 0ZM104.5 10.1551L11.9747 136.5H197.025L104.5 10.1551Z" fill="black"/>
</svg>
-->
</mask>
</defs>
//Here add some mask=url(#mask11)
<image
width="100%" height="100%" xlink:href="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQU69UnQwUGs3VTS51AEM2MRTHED0PRl0rMLVw3hdS_95xNdTPqY5_7E3N-pzgp49lrdkY&usqp=CAU"></image>
</svg>
</div>
As you see I'm trying to mask the mask11 in my image but I can't do that..I've search a lot here and its not really working I don't know how or what to do about it can anyone help me? Thanks a lot.
I'm not sure what it should look like, but here are two examples. The first uses a clip-path. With the clip-rule="evenodd" it is only the "frame" that shows.
The second is a mask. In the mask the path has a white fill – that is what makes the image show.
In both cases I made the viewBox the same aspect ratio as the image to make the image take up the entire space of the SVG.
<svg width="300" viewBox="0 0 284 178" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="cp1">
<path clip-rule="evenodd"
d="M104.5 0L0.143921 142.5H208.856L104.5 0ZM104.5 10.1551L11.9747 136.5H197.025L104.5 10.1551Z" />
</clipPath>
</defs>
<image width="100%" height="100%"
href="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQU69UnQwUGs3VTS51AEM2MRTHED0PRl0rMLVw3hdS_95xNdTPqY5_7E3N-pzgp49lrdkY&usqp=CAU"
clip-path="url(#cp1)"/>
</svg>
<svg width="300" viewBox="0 0 284 178" xmlns="http://www.w3.org/2000/svg">
<defs>
<mask id="m1">
<path d="M104.5 0L0.143921 142.5H208.856L104.5 0ZM104.5 10.1551L11.9747 136.5H197.025L104.5 10.1551Z"
fill="white"/>
</mask>
</defs>
<image width="100%" height="100%"
href="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQU69UnQwUGs3VTS51AEM2MRTHED0PRl0rMLVw3hdS_95xNdTPqY5_7E3N-pzgp49lrdkY&usqp=CAU"
mask="url(#m1)"/>
</svg>

Is it legal to put <svg> resources after </body>?

Can I put svg resources used in the website behind the end of body, in order to keep
them outside of what will be rendered?
In short: Is it legal to do the following?
<!DOCTYPE html>
<html>
<head>...</head>
<body>
<svg xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 315.424 315.424" >
<use href="#arrow" fill="rgb(0,44,89)" />
</svg>
</body>
<svg>
<g id="arrow">
<path d="M311.929,222.266l-96.119-67.342c-1.413-0.99-2.783-1.513-4.307-1.513c-3.307,0-6.471,2.512-6.471,7.313v41.05H19.886
c-4.962,0-8.854,4.132-8.854,9.094v35.563c0,4.962,3.892,9.343,8.854,9.343h185.146v40.81c0,4.801,3.167,7.19,6.474,7.19
c0.001,0-0.089,0-0.089,0c1.524,0,3.032-0.461,4.445-1.451l96.09-67.306c2.214-1.55,3.473-3.864,3.473-6.375
S314.142,223.815,311.929,222.266z" />
</g>
</svg>
</html>
As mentioned before in the comments:
It's not valid and many browser won't display your elements.
So inserting your svg assets at the top or bottom of your <body> is the preferrable method.
Caution: Hiding your asset svg via display:none will break some referenced definitions like:
filters
gradients
masks and clip-paths
It works flawlessly for shape elements (like icons)
Example
function displayNone() {
document.querySelector('#svgAssets').style.display = 'none';
}
svg {
border: 1px dotted #ccc;
height: 10em;
display: inline-block;
}
<p><button onclick="displayNone()">Set display:none</button></p>
<svg viewBox="0 0 315.424 315.424">
<use href="#arrow" fill="red" />
</svg>
<svg viewBox="0 0 100 100">
<use href="#circle" fill="green" />
</svg>
<svg viewBox="0 0 200 100">
<use href="#ellipse" fill="url(#gradient)" />
</svg>
<svg id="svgAssets" style="visibility:visible; width:0; height:0" aria-hidden="true">
<defs>
<linearGradient id="gradient">
<stop stop-color="red" offset="0%"/>
<stop stop-color="orange" offset="100%"/>
</linearGradient>
</defs>
<symbol id="arrow" viewBox="0 0 315.424 315.424">
<path d="M311.929,222.266l-96.119-67.342c-1.413-0.99-2.783-1.513-4.307-1.513c-3.307,0-6.471,2.512-6.471,7.313v41.05H19.886 c-4.962,0-8.854,4.132-8.854,9.094v35.563c0,4.962,3.892,9.343,8.854,9.343h185.146v40.81c0,4.801,3.167,7.19,6.474,7.19 c0.001,0-0.089,0-0.089,0c1.524,0,3.032-0.461,4.445-1.451l96.09-67.306c2.214-1.55,3.473-3.864,3.473-6.375 S314.142,223.815,311.929,222.266z" />
</symbol>
<symbol id="circle" viewBox="0 0 100 100">
<circle cx="50%" cy="50%" r=50% />
</symbol>
<symbol id="ellipse" viewBox="0 0 200 100">
<ellipse cx="100" cy="50" rx="100" ry="50" />
</symbol>
</svg>
In the above example I'm using <symbol> elements which could be used as an alternative to <defs>. They also support different viewBox properties for each icon.
If you just need to place icons via <use> you could also use external file references like so:
<svg viewBox="0 0 315.424 315.424">
<use href="svgIcons.svg#arrow" fill="red" />
</svg>
However, your svg files need to be same domain (or send with appropriate CORS headers)
If the purpose is not to have the original #arrow rendered in the document, you might include it inside the svg in the body, wrapped around defs.
Demo in the snipped below.
<svg xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 315.424 315.424">
<defs>
<g id="arrow">
<path d="M311.929,222.266l-96.119-67.342c-1.413-0.99-2.783-1.513-4.307-1.513c-3.307,0-6.471,2.512-6.471,7.313v41.05H19.886
c-4.962,0-8.854,4.132-8.854,9.094v35.563c0,4.962,3.892,9.343,8.854,9.343h185.146v40.81c0,4.801,3.167,7.19,6.474,7.19
c0.001,0-0.089,0-0.089,0c1.524,0,3.032-0.461,4.445-1.451l96.09-67.306c2.214-1.55,3.473-3.864,3.473-6.375
S314.142,223.815,311.929,222.266z" />
</g>
</defs>
<use href="#arrow" fill="rgb(0,44,89)" />
</svg>

Add border to an svg

I have an SVG used as a divider and I was wondering if on the curve of the svg, I can add a blue or black border that follows the path of the curve.
<svg width="100%" height="96px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none">
<path fill="#f4f6ff" d="M0,0 C40,33 66,52 75,52 C83,52 92,33 100,0 L100,100 L0,100 L0,0 Z"></path>
</svg>
Sure - just draw a path with a stroke on top of the shape.
<svg width="100%" height="96px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none">
<path fill="#f4f6ff" d="M0,0 C40,33 66,52 75,52 C83,52 92,33 100,0 L100,100 L0,100 L0,0 Z"></path>
<path fill="none" stroke="grey" stroke-width="1px" d="M0,0 C40,33 66,52 75,52 C83,52 92,33 100,0"></path>
</svg>
You can also stroke the original path and use a stroke-dasharray of the appropriate construction to make the dash cover just the top of the shape. Or you can use a svg filter to add a border to the top edge. Just drawing the border explicitly is the most straightforward.
You can use the CSS filter property if you can't directly edit the SVG to add the path (which might be a better way to go).
svg path {
filter: drop-shadow(0 -2px 0 blue);
}
<svg class="curve" width="100%" height="96px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none">
<path fill="#f4f6ff" d="M0,0 C40,33 66,52 75,52 C83,52 92,33 100,0 L100,100 L0,100 L0,0 Z"></path>
</svg>

how to set a stroke on left and right side only on a svg wave

How can i set a stroke only on the right and left side of a svg (wave svg)
<svg class="defs-only" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="wave">
<svg viewBox="0 0 100 50" preserveAspectRatio="none" >
<g>
<path d="M100,30 Q70,40 50,30 T0,30 v20 h100Z"
style="fill:red;" />
</g>
</svg>
</symbol>
</svg>
<div class="wave">
<svg style="width: 100%; height: 150px; margin-top: -150px;">
<use xlink:href="#wave"/>
</svg>
</div>
So css below gives me stroke around it, but it should only on left and right side:
svg {
stroke: #000;
}
Fiddle: https://jsfiddle.net/fe43rt4v/1/
Change the path so that the left, bottom and right edges are drawn first: M0,30 v20 h100 v-20 Q70,40 50,30 T0,30. Not 100% required, but makes things easier (otherwise you would need to compute the length of the wave).
Use stroke-dasharray to declare that you want to draw the stroke for the left edge (length 20), not for the bottom (length 100), for the right edge (length 20), and not for the rest (taking length 200 to be safe):
stroke-dasharray: 20,100,20,200;
That's it!
Fiddle: https://jsfiddle.net/fe43rt4v/2/
svg {
stroke: #000;
stroke-dasharray: 20,100,20,200;
}
<svg class="defs-only" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="wave">
<svg viewBox="0 0 100 50" preserveAspectRatio="none" >
<g>
<path d="M0,30 v20 h100 v-20 Q70,40 50,30 T0,30"
style="fill:red;" />
</g>
</svg>
</symbol>
</svg>
<div class="wave">
<svg style="width: 100%; height: 150px; margin-top: -150px;">
<use xlink:href="#wave"/>
</svg>
</div>

How use multiple SVG with different size

I try to integrate SVG icon on my web site, don't they are a thing i don't understand..
I have download 2 SVG icons :
Heart
<svg width="0" height="0" viewBox="0 0 32 32" style="position:absolute;margin-left: -100%;">
<path id ="home-icon" d="M57.062,31.398c0.932-1.025,0.842-2.596-0.201-3.508L33.884,7.785c-1.043-0.912-2.715-0.893-3.736,0.043L7.093,28.962
c-1.021,0.936-1.071,2.505-0.111,3.503l0.578,0.602c0.959,0.998,2.509,1.117,3.46,0.265l1.723-1.543v22.59
c0,1.386,1.123,2.508,2.508,2.508h8.987c1.385,0,2.508-1.122,2.508-2.508V38.575h11.463v15.804c-0.02,1.385,0.971,2.507,2.356,2.507
h9.524c1.385,0,2.508-1.122,2.508-2.508V32.107c0,0,0.476,0.417,1.063,0.933c0.586,0.515,1.817,0.102,2.749-0.924L57.062,31.398z"/>
</svg>
Project
<svg width="0" height="0" viewBox="0 0 64 64" style="position:absolute;margin-left: -100%;">
<g id="projects-icon">
<polygon points="22,6 22,10 28,16 22,22 22,26 32,16 "/>
<polygon points="10,10 10,6 0,16 10,26 10,22 4,16 "/>
<polygon points="18,12 10,20 14,20 22,12 "/>
</g>
</svg>
But the Heart icon is drawed for 32x32 and Project for 64x64, so when I try to use both on my menu, i must specify the image size in the viewBox item:
<nav id="top-menu">
<svg class="menu-icon" viewBox="0 0 32 32">
<use xlink:href="#heart-icon">
</svg>
<svg class="menu-icon" viewBox="0 0 64 64">
<use xlink:href="#project-icon">
</svg>
</nav>
Exemple on jsfiddle : http://jsfiddle.net/Nh57e/
In this case, i can't loop on my HTML and i must set size on HTML each time I want use an image.. (And if I want change the SVG, i need update all the html source for the new size :/ )
How can i do for use image without set the icon size ??
Thank all !
One solution would be to reference the whole SVGs rather than just parts of them.
In this version, we hide them in a hidden <div> rather than setting their sizes to zero:
<div style="display:none">
<svg id="project-icon" viewBox="0 0 32 32">
<g>
<polygon points="22,6 22,10 28,16 22,22 22,26 32,16 "/>
<polygon points="10,10 10,6 0,16 10,26 10,22 4,16 "/>
<polygon points="18,12 10,20 14,20 22,12 "/>
</g>
</svg>
</div>
I have taken out the width and height attributes here so that they default to 100%.
Then reference them from mini-SVGs that have the exact width and height you want:
<svg class="menu-icon" width="32px" height="32px">
<use xlink:href="#home-icon" />
</svg>
Demo here
Note. In your demo you had the viewBox sizes for the two SVGs back to front.
Another alternative is to use the symbol element. You can set a viewPort for each icon. And then reference them the same way you are currently.
<svg style="display: none;">
<symbol id="home-icon" viewBox="0 0 64 64">
<path d="M57.062,31.398c0.932-1.025,0.842-2.596-0.201-3.508L33.884,7.785c-1.043-0.912-2.715-0.893-3.736,0.043L7.093,28.962
c-1.021,0.936-1.071,2.505-0.111,3.503l0.578,0.602c0.959,0.998,2.509,1.117,3.46,0.265l1.723-1.543v22.59
c0,1.386,1.123,2.508,2.508,2.508h8.987c1.385,0,2.508-1.122,2.508-2.508V38.575h11.463v15.804c-0.02,1.385,0.971,2.507,2.356,2.507
h9.524c1.385,0,2.508-1.122,2.508-2.508V32.107c0,0,0.476,0.417,1.063,0.933c0.586,0.515,1.817,0.102,2.749-0.924L57.062,31.398z"/>
</symbol>
<symbol id="project-icon" viewBox="0 0 32 32">
<g>
<polygon points="22,6 22,10 28,16 22,22 22,26 32,16 "/>
<polygon points="10,10 10,6 0,16 10,26 10,22 4,16 "/>
<polygon points="18,12 10,20 14,20 22,12 "/>
</g>
</symbol>
</svg>
.menu-icon {
width: 32px;
height: 32px;
fill: #aaa;
}
<svg style="display: none;">
<symbol id="home-icon" viewBox="0 0 64 64">
<path d="M57.062,31.398c0.932-1.025,0.842-2.596-0.201-3.508L33.884,7.785c-1.043-0.912-2.715-0.893-3.736,0.043L7.093,28.962
c-1.021,0.936-1.071,2.505-0.111,3.503l0.578,0.602c0.959,0.998,2.509,1.117,3.46,0.265l1.723-1.543v22.59
c0,1.386,1.123,2.508,2.508,2.508h8.987c1.385,0,2.508-1.122,2.508-2.508V38.575h11.463v15.804c-0.02,1.385,0.971,2.507,2.356,2.507
h9.524c1.385,0,2.508-1.122,2.508-2.508V32.107c0,0,0.476,0.417,1.063,0.933c0.586,0.515,1.817,0.102,2.749-0.924L57.062,31.398z"/>
</symbol>
<symbol id="project-icon" viewBox="0 0 32 32">
<g>
<polygon points="22,6 22,10 28,16 22,22 22,26 32,16 "/>
<polygon points="10,10 10,6 0,16 10,26 10,22 4,16 "/>
<polygon points="18,12 10,20 14,20 22,12 "/>
</g>
</symbol>
</svg>
<nav id="top-menu">
home icon
<br/>
<svg class="menu-icon">
<use xlink:href="#home-icon" />
</svg>
<br/>
project icon
<br/>
<svg class="menu-icon">
<use xlink:href="#project-icon" />
</svg>
</nav>
Reference: css-tricks
Original demo on codepen (before I realized you can insert code snippets directly).
One way will be to edit the icons that will be listed together
so you will wrap it inside another group with consistent size