In SVG, I need the PATH stroke width to remain as is while viewBox property is changing. The SVG property vector-effect="non-scaling-stroke" should accomplish that but it is not working as it suppose to.
Can someone explain why in the code below (check the codepen.io) the stroke width still increases as viewbox changes? I would also appreciate a solution that makes strokes width constant regardless of viewbox.
https://codepen.io/anon/pen/eKQrYL
HTML
<div class="Item">
<div class="Item-graphic">
<svg id='scaling-stroke' width="200" height="200" viewBox="0 0 50 50">
<circle cx="25" cy="25" r="20" fill="none" stroke="#fff" stroke-width="2"/>
<path d="M25 15 L 25 35" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round"/>
<path d="M15 25 L 35 25" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round"/>
</svg>
</div>
<span>
50 x 50 view box<br>
200 x 200 dimensions<br>
no vector effect
</span>
</div>
<div class="Item">
<div class="Item-graphic">
<svg id='non-scaling-stroke' width="200" height="200" viewBox="0 0 50 50">
<circle cx="25" cy="25" r="20" fill="none" stroke="#fff" stroke-width="2" vector-effect="non-scaling-stroke"/>
<path d="M25 15 L 25 35" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke"/>
<path d="M15 25 L 35 25" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke"/>
</div>
</svg>
<span>
50 x 50 view box<br>
200 x 200 dimensions<br>
vector effect
</span>
</div>
CSS
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
background-color: #2196F3;
font-family: Helvetica, sans-serif;
font-weight: 300;
line-height: 1.5;
}
svg {
display: block;
margin: 0 auto;
}
.Item {
flex: 0 0 200px;
padding: 0 1rem;
color: rgba(#fff, 0.6);
font-size: 11px;
text-align: center;
}
.Item-graphic {
display: flex;
align-items: center;
height: 220px;
}
JS
n=1;inc=1;
cvb = function(){
vb = '' + n
vb += ' ' + n
vb += ' ' + 2*(25-n)
vb += ' ' + 2*(25-n)
$('#non-scaling-stroke').attr('viewBox', vb)
$('#scaling-stroke').attr('viewBox', vb)
n += inc;
if (n<=1 || n>=24) inc *= -1;
setTimeout(cvb, 100);
};
cvb()
It is a bug in Chrome. The bug report is here https://bugs.chromium.org/p/chromium/issues/detail?id=849080. It was fixed in Chrome version 68.0.3440.25.
Related
Need some help with filling my svg with color on hover.
On the left I have my test svg, on the right - the result I want on hover.
How to fill with color on hover only gray lines and let the space inside be transparent (empty)?
(that's strange that space inside is fillinbg with color, because there is no svg content there)
.container {
width: 50%;
margin: 0 auto;
display: flex;
justify-content: space-between;
background: gray;
padding: 20px;
}
svg:hover {
fill: #40bfff;
stroke:#40bfff;
}
<div class="container">
<div>
<svg width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7.188 19a.562.562 0 100-1.125.562.562 0 000 1.125zM15.063 19a.562.562 0 100-1.125.562.562 0 000 1.125z" fill="#9098B1" stroke="#9098B1" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M1 1h2.25L5.5 14.5h11.25L19 4.375H4.375" stroke="#9098B1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
<!-- changing stroke and fill to color i need -->
<div>
<svg width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7.188 19a.562.562 0 100-1.125.562.562 0 000 1.125zM15.063 19a.562.562 0 100-1.125.562.562 0 000 1.125z" fill="#40bfff" stroke="#40bfff" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M1 1h2.25L5.5 14.5h11.25L19 4.375H4.375" stroke="#40bfff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
</div>
All you have to do to change the wheel fill colour is add a second rule targetting the wheels.
Note: The SVG below is exactly the same as your original one. Except that I have reformatted it a little, and added a viewBox so that we can scale it up to see the wheels. I wanted to show that you can style the SVG how you want without having to change the SVG.
svg {
/* just here to make the svg large enough to see the wheel centres */
width: 200px;
height: 200px;
}
svg:hover path {
stroke: #40bfff;
}
/* Target the first path (the wheels) */
svg:hover path:nth-child(1) {
fill: #40bfff;
}
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.188 19a.562.562 0 100-1.125.562.562 0 000 1.125zM15.063 19a.562.562 0 100-1.125.562.562 0 000 1.125z"
fill="#9098B1" stroke="#9098B1"
stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1 1h2.25L5.5 14.5h11.25L19 4.375H4.375"
stroke="#9098B1"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
try this:
.container {
width: 50%;
margin: 0 auto;
display: flex;
justify-content: space-between;
background: gray;
padding: 20px;
}
svg:hover path {
stroke: #40bfff;
}
<div class="container">
<div>
<svg width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7.188 19a.562.562 0 100-1.125.562.562 0 000 1.125zM15.063 19a.562.562 0 100-1.125.562.562 0 000 1.125z" fill="#9098B1" stroke="#9098B1" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M1 1h2.25L5.5 14.5h11.25L19 4.375H4.375" stroke="#9098B1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
<!-- changing stroke and fill to color i need -->
<div>
<svg width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7.188 19a.562.562 0 100-1.125.562.562 0 000 1.125zM15.063 19a.562.562 0 100-1.125.562.562 0 000 1.125z" fill="#40bfff" stroke="#40bfff" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M1 1h2.25L5.5 14.5h11.25L19 4.375H4.375" stroke="#40bfff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
</div>
Put all your stroke & fill attributes into the svg element since that's where your hover is set.
.container {
width: 50%;
margin: 0 auto;
display: flex;
justify-content: space-between;
background: gray;
padding: 20px;
}
svg:hover {
fill: none;
stroke: #40bfff;
}
<div class="container">
<div>
<svg width="20" height="20" stroke="#9098B1" fill-opacity="0" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round">
<path d="M7.188 19a.562.562 0 100-1.125.562.562 0 000 1.125zM15.063 19a.562.562 0 100-1.125.562.562 0 000 1.125z" />
<path d="M1 1h2.25L5.5 14.5h11.25L19 4.375H4.375"/>
</svg>
</div>
I need to repeat an svg <pattern> on a horizontal <rect>.
I mean, the svg <rect> is larger that the pattern, so I need it to repeate horizontally on whatever space is left.
I want the main pattern to appear in the center, which is exactly what is happening now. I just need to make it repeat on both sides.
Right now, I can only get it to show once.
Note:
The pattern is the black triangle
The 1px dotted red border is from the svg element
.mySvg {
width: 600px;
height: 50px;
border: 1px dotted red;
}
<svg class="mySvg">
<defs>
<pattern id="wave" viewBox="0,0,150,50" width="100%" height="100%">
<path d="M 0 50 l 75 -50 l 75 50" stroke="black" stroke-width="2"/>
</pattern>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="url(#wave)"/>
</svg>
How can I make the pattern repeat on the space that is left?
Use the SVG as background:
.box {
height:50px;
border:1px solid red;
margin: 5px;
background:
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 -2 150 52"><path d="M 0 50 l 75 -50 l 75 50" stroke="black" /></svg>')
center/auto 100%;
}
<div class="box"></div>
<div class="box" style="height:100px;"></div>
In your code the pattern is having a width of 100%. It can't repeat. I gave the pattern a width of 25%. Also to make it fall in the middle I'm offsetting the pattern a 12.5% (25/2)
x="12.5%"
.mySvg {
width: 600px;
height: 50px;
border: 1px dotted red;
}
<svg class="mySvg" viewBox="0 0 600 50">
<defs>
<pattern id="wave" x="12.5%" y="0" width="25%" height="100%">
<path d="M 0 50 l 75 -50 l 75 50" stroke="black" stroke-width="2"/>
</pattern>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="url(#wave)"/>
</svg>
I have an issue with font size on SVG as us can see in svg the font-size:16px different from paragraph font-size but the they have the same value 16px. I would like to have font size in svg such on paragraph.
The second issue, it's how to center <tspan text-anchor="middle" class="tc-label-value">85</tspan> when I delete <tspan class="label-text" text-anchor="middle" x="0" y="50" dy="15">Text in SVG</tspan>
I mean the is a case when I have Text in svg and have not
https://codepen.io/palaniichukdmytro/pen/BaaKbze
SVG text, & span font-size and center solution
body {
margin: 0;
}
.wr {
width: 180px;
margin: 0 auto;
}
.label-text {
font-size: 12px;
text-align: center;
}
.tc-label-value {
font-size: 12px;
text-align: center;
}
.par {
font-size: 16px;
text-align: center;
}
<div class='wr'>
<svg viewBox="0 0 100 100" width="100%" height="100%" style="display: block;">
<path d="M 95.5 50 A 45.5 45.5 0 1 1 11.315120324302569 26.047336589080288" stroke-width="9" stroke-dasharray="168.16760675098308" stroke-dashoffset="2.842170943040401e-14" stroke="#a3bfff" stroke-linecap="round" fill="none" style="transition: stroke-dashoffset 500ms ease-out 0s;"></path>
<path d="M 11.315120324302569 26.047336589080288 A 45.5 45.5 0 0 1 95.5 49.999999999999986" stroke-width="9" stroke-dasharray="117.71732472568812" stroke-dashoffset="0" stroke="#66bb6a" stroke-linecap="round" fill="none" style="transition: stroke-dashoffset 500ms ease-out 0s;"></path>
<text transform="translate(50)" x="0" y="50">
<tspan text-anchor="middle" class="tc-label-value">85</tspan>
<tspan class="label-text" text-anchor="middle" x="0" y="50" dy="15">Text in SVG</tspan>
</text>
</svg>
<p class='par'>Text Paragraph</p>
</div>
The font size for the svg element should be 8.88px. Why? Because the svg's width is 100 units or px ( viewBox="0 0 100 100" ) and is scaled up to 180px ( .wr{width: 180px;} ). Since you need the font size inside the svg to look like 16px, the real font size should be 16 * 100 / 180 = 8.88
.wr {
width: 180px;
}
.par{
font-size: 16px;
}
svg{font-size: 8.88px;}
<div class='wr'>
<svg viewBox="0 0 100 100" style="display: block;">
<path d="M 95.5 50 A 45.5 45.5 0 1 1 11.315120324302569 26.047336589080288" stroke-width="9" stroke-dasharray="168.16760675098308" stroke-dashoffset="2.842170943040401e-14" stroke="#a3bfff" stroke-linecap="round" fill="none" style="transition: stroke-dashoffset 500ms ease-out 0s;"></path>
<path d="M 11.315120324302569 26.047336589080288 A 45.5 45.5 0 0 1 95.5 49.999999999999986" stroke-width="9" stroke-dasharray="117.71732472568812" stroke-dashoffset="0" stroke="#66bb6a" stroke-linecap="round" fill="none" style="transition: stroke-dashoffset 500ms ease-out 0s;"></path>
<text transform="translate(50)" x="0" y="50">
<tspan text-anchor="middle" class="tc-label-value">85</tspan>
<tspan class="label-text" text-anchor="middle" x="0" y="50" dy="15">Text in SVG</tspan>
</text>
</svg>
<p class='par'>Text Paragraph</p>
</div>
I'm trying to create this nav using an SVG. I was provided with an SVG however it didn't work out so someone on SO helped me make another. However now I am unsure how to create the nav using
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xl="http://www.w3.org/1999/xlink" version="1.1"
width="576" height="152" viewbox="0 0 576 152">
<path transform="translate(10,-185)" d="M 0 189.5 L 39.741071 261.25 L 0 333.125 L 516.63393 332 L 556.375 260 L 516.63393 188 L 0 189.5 Z" stroke="black" stroke-linecap="butt" stroke-linejoin="miter" stroke-width="10" fill="transparent" />
</svg>
My current nav looks like
<nav>
<ul>
<li class="completed">Exam <i class="fa fa-check-circle"></i></li>
<li>Personal <i class="fa fa-times-circle"></i></li>
<li>Employment</li>
<li>Appointment</li>
<li>Record Check</li>
<li>Submit</li>
</ul>
</nav>
With just a white background. So it looks close to what the image looks like just minus the SVG shape.
First, your SVG needed a little changes to correctly scale itself (with preserveAspectRatio="none") and some more adjusts to your specific layout:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" width="576" height="152" viewbox="0 0 576 152" preserveAspectRatio="none">
<path transform="translate(10, -185)" d="M 0 189.5 L 39.741071 261.25 L 0 333.125 L 516.63393 332 L 556.375 260 L 516.63393 188 L 0 189.5 Z" stroke="black" stroke-opacity="0.1" stroke-linecap="butt" stroke-linejoin="miter" stroke-width="2" fill="white" />
</svg>
And here's the CSS using it:
nav ul {
margin: 0;
padding: 0;
list-style: none;
display: flex;
flex-flow: row wrap;
}
nav li {
background: url('path/to/your.svg') no-repeat;
background-size: 100% 100%;
flex: 1 1 auto;
margin: 0 -5px;
}
nav a {
display: block;
font: bold 1rem Sans-serif;
color: rgba(0, 0, 0, .25);
padding: 1em 2em;
text-align: center;
text-decoration: none;
}
nav li.completed a {
color: rgba(0, 0, 0, .5);
}
If you like, here's a working sample.
I have this SVG :
<svg class="decor" height="100%" preserveAspectRatio="none" version="1.1" viewBox="0 0 100 100" width="100%" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0 L50 100 L100 0 L100 100 L0 100" stroke-width="0"></path>
</svg>
This works but I need to have transparent outer and black color inner. In my code this is currently inverse.
How to generate this?
DEMO
Just change the coordinates of your SVG path (d attribute) to form a triangle instead of the shape.
The modified path (d="M0 0 L50 100 L100 0z") works as follow:
M0 0 - Moves the pen to 0,0 (top left corner)
L 50 100 - Draws a line from 0,0 to 50,100 (which is bottom center point)
L 100 0 - Draws a line from 50,100 to 100 0 (which is top right corner)
z - Closes the path by drawing a line from the last point (100,0) to the first point (0,0)
SVG path elements by default get a black colored fill and hence the triangle gets colored black whereas the outside remains transparent.
* {
background: #e1e1e1;
}
.decor {
height: 80px
}
<div class="decor">
<svg class="decor" height="100%" preserveAspectRatio="none" version="1.1" viewBox="0 0 100 100" width="100%" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0 L50 100 L100 0z" stroke-width="0"></path>
</svg>
</div>
Clip Image using Path:
If the need is to use the path to clip background image into the required shape then it would be better to use clipPath element and clip-path CSS property like in the below snippet:
* {
background: #e1e1e1;
}
.decor {
height: 80px;
background: url(http://lorempixel.com/200/80);
-webkit-clip-path: url(#clipper);
clip-path: url(#clipper);
}
<div class="decor">
<svg height="0" preserveAspectRatio="none" version="1.1" viewBox="0 0 100 100" width="0" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="clipper" clipPathUnits="objectBoundingBox">
<path d="M0 0 L.5 1 L1 0z"></path>
</clipPath>
</defs>
</svg>
</div>
Putting all the pieces together, the below code should achieve the output that was provided in the image.
.div-1 {
position: relative;
height: 500px;
width: 100%;
}
.decor-top {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('http://lorempixel.com/550/500');
-webkit-clip-path: url(#clipper);
clip-path: url(#clipper);
}
.div-2 {
position: absolute;
bottom: 0;
left: 0;
height: 50%;
width: 100%;
background-image: url('http://kinderhtml.themerex.net/img/bg/texture_2.png');
background-color: green;
-webkit-clip-path: url(#clipper2);
clip-path: url(#clipper2);
}
<div class="div-1">
<div class="decor-top">
<svg height="0" preserveAspectRatio="none" version="1.1" viewBox="0 0 100 100" width="0" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="clipper" clipPathUnits="objectBoundingBox">
<path d="M0 0 L.5 .1 L1 0 1,1 0,1z"></path>
</clipPath>
</defs>
</svg>
</div>
<div class="div-2">
<svg height="0" preserveAspectRatio="none" version="1.1" viewBox="0 0 100 100" width="0" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="clipper2" clipPathUnits="objectBoundingBox">
<path d="M0 0 L.5 .25 L1 0 1,1 0,1z"></path>
</clipPath>
</defs>
</svg>
</div>
</div>
The original path (d="M0 0 L50 100 L100 0 L100 100 L0 100") worked as follows:
M0 0 - Moves the pen to 0,0 (top left corner)
L 50 100 - Draws a line from 0,0 to 50,100 (which is bottom center point)
L 100 0 - Draws a line from 50,100 to 100 0 (which is top right corner)
L 100 100 - Draws a line from 100,0 to 100,100 (which is bottom right corner)
L0 100 - Draws a line from 100,100 to 0,100 (which is bottom left corner)
Thus the above path ends up a forming a shape which looks like a rectangle with a triangle cut-out at the top.