Why will my SVG background file not scale up? - svg

My problem is that the browser does not listen to background-size. I even tried to set preserveAspectRatio to none in the SVG but it still does not work.
It should not resize with aspect ratio. Stretching out is fine..
SVG file
To have it a background image in my example, I use a data:image. If you want to know what the SVG file looks like, it's here below:
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<path d="M 10 10 C 20 20, 40 20, 50 10" fill="000"/>
</svg>
Example
What I expect is that black "banana" to change size to something bigger. I set it to 100px so it should span all the way to the end of the div.
div {
height: 100px;
width: 100px;
background: #eee;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='none'%3E%3Cpath d='M 10 10 C 20 20, 40 20, 50 10' fill='000'/%3E%3C/svg%3E");
background-position: center 0;
background-size: 100px 100px;
background-repeat: no-repeat;
}
<div></div>

Because your SVG will take any width or height, and your path is in a fixed position and size, no CSS will do the trick because the scaling won't do anything. Instead, add a viewBox to your SVG. Your SVG will now look like this.
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" viewBox="10 10 40 7.5">
<path d="M 10 10 C 20 20, 40 20, 50 10" fill="000"/>
</svg>
div {
height: 100px;
width: 100px;
background: #eee;
background-image: url("https://drive.google.com/uc?id=1_W7AIhdfiwxgU0_FrTsYwyVrZvjzxt18&export=download");
background-position: center 0;
background-size: cover;
background-repeat: no-repeat;
}
<div></div>
By the way, the drive file background image is just the svg.

A viewbox is needed. Thanks to #enxaneta.
viewBox='10 10 40 7.5'

Related

How can I make this SVG polygon "wedge" always have 45 degree ends?

I'm trying to make this wedge shape has 45 degree angles at both ends.
As the size of its containing div changes, or the page is zoomed, that angle changes:
Here's my (abbreviated) code:
<div class="relative">
<svg class="h-16p top-0 left-0 absolute w-full fill-current" viewBox="0 0 100 4" preserveAspectRatio="none">
<polygon points="0,0 100,0 95,5 5,5" />
</svg>
</div>
I'm using tailwindCSS - for those not familiar those classes translate to:
position: absolute;
width: 100%;
fill: currentColor;
height: 16px;
top: 0px;
left: 0px;

SVG - Partially stroking a triangle

I have a simple triangle SVG and I'm stuck trying to figure out how I can partially apply borders like I would in CSS? How would I go about just applying a stroke to just the left and the right side of the triangle but not the top?
https://jsfiddle.net/rf8a9xzy/1/
<span class="svg-triangle">
<svg width="100%" viewBox="0 0 20 10">
<polygon points="0,10 20,10 10,0" />
</svg>
</span>
You can use stroke-dasharray to set the parts of the stroke that you want to draw.
Dasharrays are made up of one or more pairs of numbers describing the length to draw, followed by the length to skip. It always starts with the drawn length. So a dasharray of "10 5" means draw a stroke section of length 10, followed by a gap of length 5. It then repeats. Draw another 10 and a gap of 5 etc.
Your triangle starts with a horizontal line of length 20, followed by two 45deg lines (of 10,10). The length of those other two sides are 14.142 - derived using Pythagoras' Theorem: sqrt(10^2 + 10^2).
So the dash array to draw the two sides would need to be:
0 20 28.284
Thats:
draw a stroke of 0,
a gap of 20 (the horizontal part of the triangle)
draw the two other sides (14.142 * 2)
.svg-triangle {
display: block;
width: 100px;
transform: rotate(180deg);
}
.svg-triangle svg {
fill: #FFF;
stroke: #000;
stroke-width: 1px;
stroke-opacity: 0.2;
}
.svg-triangle svg polygon{
stroke-dasharray: 0 20 28.284;
}
<span class="svg-triangle">
<svg width="100%" viewBox="0 0 20 10">
<polygon points="0,10 20,10 10,0" />
</svg>
</span>

css solution for responsive SVG chart (polyline coordinates)

I'm using javascript to generate the points coordinates of a polyline element inside a line chart. The chart must have a fixed height (210px) and a responsive width (always 100% of its parent div).
Problem is the points coordinates of the polyline don't change when resizing the window.
Is there a way to set the coordinates of the polyline as percentage of its parent div so that the horizontal coordinates change when resizing the window ?
I know I could use javascript to listen for window resize and recalculate the points coordinates of the polyline but it seems somewhat overkill so I was hoping there was a lighter, pure CSS solution.
Fiddle: https://jsfiddle.net/Hal_9100/1cnq389g/
You need to add a viewBox to your SVG. If you want the graph to stretch horizontally, to fit the box, then you'll also want to add a suitable preserveAspectRatio value.
* {padding: 0; margin: 0;}
#container {
width: 60%; height: 210px;
background: #fff;
}
svg {
width: 100%; height: 210px;
position: relative;
border: 2px solid black;
}
<div id="container">
<svg viewBox="0 0 450 210" preserveAspectRatio="none">
<polyline id="myLine" fill="none" stroke="#2681DC" stroke-width="2" points="0,210 50,67 100,174 150,198 200,202 250,190 300,205 350,207 400,198 450,19 "></polyline>
</svg>
</div>
https://jsfiddle.net/1cnq389g/2/

prevent path deformation made by preserveAspectRatio="none"

I'd like to prevent <path> elements from stretching caused bypreserveAspectRatio="none" on <svg> tag.
I've found nearly perfect solution adding this attribute to <path> elements:
vector-effect="non-scaling-stroke"
But I need them to be scalable with transform="scale()" which is also disabled or more precisely their stroke-width are fixed and not scalable. So, my question is:
Is there any way to prevent stretching but not zooming?
Ok, to make it more clear: https://codepen.io/lukydorny/pen/aNYOdW
I would like to shape a path by different viewBox width and height (2nd image) but I need horizontal line to be of same width as vertical(3rd image). And then I wish I was able to scale it exactly the same way as original path(4th image) which is disabled as you can see in the last image.
Is there any way how to do it?
Yes, you can achieve this simply by defining the SVG element like this:
<svg
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="100%"
height="100%"
viewBox="0 0 1920 1080"
style="display:block">
... your SVG paths code here
</svg>
Notice the "viewBox" size should be the size of your "svg document" (maximum x and maximum y values).
This preserves the aspect ratio you define; however, be aware that your paths created should comply with the size you define, else it may cause problems.
To "zoom" the whole graphic, simply change with width & height of the SVG element, or its parent element, or use "scale()" inside the SVG, or with JavaScript as you normally would.
Would this option work?
svg {
border: solid 1px
}
<div title='original path' style='float:left;'>
<svg width=192px height=54px viewBox='0 0 200 200'>
<path style="stroke-linejoin: round; stroke-linecap: round; opacity: 1; stroke: rgb(50, 122, 97); stroke-width: 8px; fill: none;" d="m30 68.709l5,0,4.111,0,3.444,0,3.555,0,4.111,0.071,5,0.214,5.222,0.428,5.222,0.571,5,0.642,4.778,0.571,4.778,0.428,4.778,0.214,5.111,0.071,4.778,0,4.333,0,3.667,0,3.444,0,3.333,0,3.222,0,3,0,2.556,0,2.111,-0.071,1.889,-0.214,1.778,-0.499,1.778,-0.785,1.445,-1.07,1.111,-1.284,0.778,-1.498,0.556,-2.069,0.444,-2.64,0.222,-3.211,0.111,-2.997,0,-2.569,0,-1.998,0,-1.998,0,-2.283,0,-2.64,0,-2.497,0,-2.069,0,-1.569,-0.556,-1.284,-1.556,-1.07,-3,-0.785,-3.778,-0.499,-4.222,-0.214,-4.222,-0.071,-4.889,0,-5.333,0,-6,0,-5.778,-0.071,-5.778,-0.214,-5.556,-0.428,-5.556,-0.571,-5.889,-0.571,-5.889,-0.428,-5.778,-0.214,-4.445,-0.143,-3.333,-0.143,-2.444,-0.214,-2.333,-0.214,-2.333,-0.214,-2.222,-0.214,-2,-0.214,-1.778,-0.214,-1.667,-0.214,-1.778,-0.071,-1.778,0.357,-1.667,1.926,-1.222,3.781,-0.778,5.494,-0.333,5.28,-0.111,4.495,0,3.568,0,3.496,0,4.21,0,4.923,0,5.494,0,4.78,0,3.996,0,3.282,0,3.14,0,3.354,0,3.496,0.111,3.568,0.333,2.854,0.667,2.069,1.111,1.427,1.445,1.213,1.778,0.999,1.778,0.713,1.889,0.499,1.889,0.499,2.111,0.499,2.889,0.571,4.111,0.571,5.778,0.713,6.778,0.713,7.333,0.642,7,0.428,6.333,0.214,5.778,0.071,5.667,0,6.111,0,7.111,0,8.111,0,8.556,0,7.333,0,5.667,-0.071,4.444,-0.143,4.333,-0.285,4.556,-0.285,4.667,-0.285,4.556,-0.143,4.333,-0.143,4,-0.143,3.333,-0.214,2,-0.143,0,0"></path>
</svg>
</div>
<div title='original path' style='float:left;'>
<svg width=192px height=108px viewBox='0 0 200 200'>
<path style="stroke-linejoin: round; stroke-linecap: round; opacity: 1; stroke: rgb(50, 122, 97); stroke-width: 8px; fill: none;" d="m30 68.709l5,0,4.111,0,3.444,0,3.555,0,4.111,0.071,5,0.214,5.222,0.428,5.222,0.571,5,0.642,4.778,0.571,4.778,0.428,4.778,0.214,5.111,0.071,4.778,0,4.333,0,3.667,0,3.444,0,3.333,0,3.222,0,3,0,2.556,0,2.111,-0.071,1.889,-0.214,1.778,-0.499,1.778,-0.785,1.445,-1.07,1.111,-1.284,0.778,-1.498,0.556,-2.069,0.444,-2.64,0.222,-3.211,0.111,-2.997,0,-2.569,0,-1.998,0,-1.998,0,-2.283,0,-2.64,0,-2.497,0,-2.069,0,-1.569,-0.556,-1.284,-1.556,-1.07,-3,-0.785,-3.778,-0.499,-4.222,-0.214,-4.222,-0.071,-4.889,0,-5.333,0,-6,0,-5.778,-0.071,-5.778,-0.214,-5.556,-0.428,-5.556,-0.571,-5.889,-0.571,-5.889,-0.428,-5.778,-0.214,-4.445,-0.143,-3.333,-0.143,-2.444,-0.214,-2.333,-0.214,-2.333,-0.214,-2.222,-0.214,-2,-0.214,-1.778,-0.214,-1.667,-0.214,-1.778,-0.071,-1.778,0.357,-1.667,1.926,-1.222,3.781,-0.778,5.494,-0.333,5.28,-0.111,4.495,0,3.568,0,3.496,0,4.21,0,4.923,0,5.494,0,4.78,0,3.996,0,3.282,0,3.14,0,3.354,0,3.496,0.111,3.568,0.333,2.854,0.667,2.069,1.111,1.427,1.445,1.213,1.778,0.999,1.778,0.713,1.889,0.499,1.889,0.499,2.111,0.499,2.889,0.571,4.111,0.571,5.778,0.713,6.778,0.713,7.333,0.642,7,0.428,6.333,0.214,5.778,0.071,5.667,0,6.111,0,7.111,0,8.111,0,8.556,0,7.333,0,5.667,-0.071,4.444,-0.143,4.333,-0.285,4.556,-0.285,4.667,-0.285,4.556,-0.143,4.333,-0.143,4,-0.143,3.333,-0.214,2,-0.143,0,0"></path>
</svg>
</div>

Text border using css (border around text)

Is there a way to integrate a border around text like the image below?
Use multiple text shadows:
text-shadow: 2px 0 #fff, -2px 0 #fff, 0 2px #fff, 0 -2px #fff,
1px 1px #fff, -1px -1px #fff, 1px -1px #fff, -1px 1px #fff;
body {
font-family: sans-serif;
background: #222;
color: darkred;
}
h1 {
text-shadow: 2px 0 #fff, -2px 0 #fff, 0 2px #fff, 0 -2px #fff,
1px 1px #fff, -1px -1px #fff, 1px -1px #fff, -1px 1px #fff;
}
<h1>test</h1>
Alternatively, you could use -webkit-text-stroke, which produces a slightly different result because it modifies the stroke width instead of adding additional shadows around the text. Despite the webkit prefix, it works in most browsers (including Firefox) as of 2022:
-webkit-text-stroke: 2px #fff;
body {
font-family: sans-serif;
background: #222;
color: darkred;
}
h1 {
-webkit-text-stroke: 2px #fff;
}
<h1>test</h1>
Also, read more at CSS-Tricks.
Sure. You could use CSS3 text-shadow :
text-shadow: 0 0 2px #fff;
However it wont show in all browsers right away. Using a script library like Modernizr will help getting it right in most browsers though.
I don't like that much solutions based on multiplying text-shadows, it's not really flexible, it may work for a 2 pixels stroke where directions to add are 8, but with just 3 pixels stroke directions became 16, and so on...
Not really confortable to manage.
The right tool exists, it's SVG <text>
The browsers' support problem worth nothing in this case, 'cause the usage of text-shadow has its own support problem too,
filter: progid:DXImageTransform can be used or IE < 10 but often doesn't work as expected.
To me the best solution remains SVG with a fallback in not-stroked text for older browser:
This kind of approuch works on pratically all versions of Chrome and Firefox, Safari since version 3.04, Opera 8, IE 9
Compared to text-shadow whose supports are:
Chrome 4.0,
FF 3.5,
IE 10,
Safari 4.0,
Opera 9, it results even more compatible.
.stroke {
margin: 0;
font-family: arial;
font-size:70px;
font-weight: bold;
}
svg {
display: block;
}
text {
fill: black;
stroke: red;
stroke-width: 3;
}
<p class="stroke">
<svg xmlns="http://www.w3.org/2000/svg" width="700" height="72" viewBox="0 0 700 72">
<text x="0" y="70">Stroked text</text>
</svg>
</p>
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
The following will cover all browsers worth covering:
text-shadow: 0 0 2px #fff; /* Firefox 3.5+, Opera 9+, Safari 1+, Chrome, IE10 */
filter: progid:DXImageTransform.Microsoft.Glow(Color=#ffffff,Strength=1); /* IE<10 */

Resources