SVG viewBox="0 0 100 100" wont scale my path to 100%? - css

I currently have an svg path that only shows about 50%. How can I get it to show 100%?
Here is my code:
<div className="svgPathContainer">
<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
<path d="M82 88L0 0H123V170H0L82 88Z" fill="#F9B300" />
</svg>
</div>
I have className="svgPath" set as:
.svgPathContainer{
width: 100%;
height: 100%;
}
Here is also an example of the svg only showing at 50%:
https://codesandbox.io/s/svg-scaling-fff1q?file=/src/App.js:93-357
The problem: Why wont the svg path scale to 100% of the .svgPathContainer?

The viewBox is like a canvas size. So drawings outside of this view box will be clipped. Like css overflow: hidden. And your drawing has a size of width 123px and height 170px. So you have to change the view box to this value. Check our some docs.
If you want to keep the viewbox of 100 x 100 px, you need to change your drawing element size (path).
The view box has nothing to do with the scale. It's just the canvas size. A rect clip with width, height and offset (x y w h) for the SVG elements inside. And the SVG tag's width and height attributes are for scale the rendered image.
<div className="svgPathContainer">
<svg width="100%" height="100%" viewbox="0 0 123 170" preserveAspectRatio="none">
<path d="M82 88L0 0H123V170H0L82 88Z" fill="#F9B300" />
</svg>
</div>

Related

How to scale svg size to exactly wrap its content?

I have a very simple svg with a circle inside:
<div>
<svg className="main-svg">
<circle pathLength="25" cx="50%" cy="50%" r="25%" />
</svg>
</div>
Then if I style it:
svg {
height: 250px;
width: 250px;
}
The svg will take up 250px width and height, but the circle inside it will be much smaller, so there's unwanted white space around the circle. Is it possible to make the svg wrap the circle without adding space, so that defining the width of height of the svg will result in setting the width and height of the circle inside it?
Stackblitz link: https://stackblitz.com/edit/react-ts-fwmjzn?file=style.css
Set radius attribute value to 50%
svg {border: 2px solid red; }
<svg width="250" height="250" viewBox="0 0 250 250">
<circle pathLength="25" cx="50%" cy="50%" r="50%" />
</svg>

How to make an svg element responsive to it's parent container?

I'm trying to acheive this:
Rendering an svg square (w:h = 1:1 rectangular) inside of div,
when the div's width is greater than height, the square should fit into the container by the height(red box is the div, green box is the svg square):
When the div's height is greater than width, the squire should fit into the container by the width:
It can be easily achieved by specifying the size of the svg view port.But if I remove the size of the svg view port, instead when I add the size to the parent div(red box), it refuses to look at the height of the container, the image turns to be:
Is there a way we can make the square responsive to the container height?
here is my code:
#main {
width: 400px;
height: 100px;
border: 4px solid red;
}
<div id="main">
<svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid Meet">
<rect x="0" y="0" width="100" height="100" fill="green"/>
</svg>
</div>
Just set the width and height attributes of the SVG to "100%". Either in the SVG, or via CSS.
Secondly, fix your other attributes:
viewBox values should not have commas.
it is preserveAspectRatio, not preserveAspect, and meet, not Meet
#main {
width: 400px;
height: 100px;
border: 4px solid red;
}
<div id="main">
<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">
<rect x="0" y="0" width="100" height="100" fill="green"/>
</svg>
</div>

How to scale svg to viewport, but keep aspect ratio on filled image

I want to fill a viewport with an svg, and add a fill to a path in this svg.
When I set preserveAspectRatio="xMinYMin slice" to the image pattern, it will preserve it's aspect ratio nicely, but the path will not scale.
If I then add preserveAspectRatio="none" to the svg element, the whole element will fit to the viewport, but my image will not scale properly.
What am I overlooking?
<svg height="100%" width="100%" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 750" preserveAspectRatio="none">
<defs>
<pattern id='home' width="1" height="1" preserveAspectRatio="xMinYMin slice">
<image xlink:href='https://i.imgur.com/4AiXzf8.jpg' width="100%" height="100%" preserveAspectRatio="xMinYMin slice"></image>
</pattern>
</defs>
<path id="bg" class="cls-1" d="M0,0V622.58S250,711,683,711s683-88.42,683-88.42V0Z"style="fill: url(#home)"></path>
</svg>
If you set the whole SVG to preserveAspectRatio="none", then everything inside the SVG will stretch and there is no way to counteract that. So you have to do it a different way.
What we have to do is remove the viewBox and the preserveAspectRatio and just set the width of the SVG to 100% and the height to the height of our <path> (711px). That way the SVG viewport fills the width of the page and keeps it's height at the size we want.
The next step is to move the <image> out of the <pattern>, make its width and height 100% x 100% and set preserveAspectRatio="xMinYMin slice". So it now scales to fill our wide SVG, and keeps its aspect ratio.
The last step is to apply a <clipPath> to the image to give it the shape we want. To get the clip path to automatically fit itself to the <image>, we need to use clipPathUnits="objectBoundingBox".
The thing with objetBoundingBox units is that (0,0) represents the top left of the element it is applied to, and (1,1) corresponds to the bottom-right of the element it is applied to. But our path is much bigger than that. It has a width and height of 1366x711.
To fix that, we need to scale the path so that it is only 1x1 in size, instead of 1366x711. So we apply a transform and scale it by 1/1366 in X, and 1/711 in Y.
transform="transform="scale(0.000732, 0.001406)"
The final result is this:
body {
margin: 0;
padding: 0;
}
<svg width="100%" height="711px" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="clip" clipPathUnits="objectBoundingBox">
<path d="M0,0V622.58S250,711,683,711s683-88.42,683-88.42V0Z"
transform="scale(0.000732, 0.001406)"></path>
</clipPath>
</defs>
<image xlink:href='https://i.imgur.com/4AiXzf8.jpg' width="100%" height="100%" preserveAspectRatio="xMinYMin slice"
clip-path="url(#clip)"></image>
</svg>
remove height and preserveAspectRatio but keep viewBox as it is and width at 100%.

viewBox misunderstanding - why the rectangle appears in the middle

see this simple code code:
<svg width="400" height="400" viewBox="0 0 50 200">
<rect width="50" height="200" style="fill:blue"/>
</svg>
expected result:
the viewBox settings will perfectly crop the rectangle, then stretch it across 400x400 svg viewPort.
resulting in 400x400 blue square.
actual result
blue rectangle, in the middle of the svg viewport, with white marigins in the sides.
what did i miss?

Set css in svg element

I have a svg image element. I have to set margin for image.
<svg id="chart" preserveAspectRatio="xMidYMid" viewBox="0 0 960 500">
<image class="leaf" x="240.9471668231492" y="362.4164063706163" width="80" height="80" href="http://upload.wikimedia.org/wikipedia/commons/a/ac/ML_maple_leaf.png"></image>
<svg>
My css is:-
.leaf
{
margin-top:80px;
}
Why my css is not working. Is there any othere way to set css in svg.
AFAIK, the SVG standard doesn't specify anything like margin, which is why it's handled inconsistently. Just set the correct x and y of your image and the correct size of your svg

Resources