Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

resize svg wrapped in div that is wrapped in div

Tags:

html

svg

I'm having a problem coverting inline SVG to be wrapped in divs. I was using nested SVGs before and now I'm told I have to use nested divs with inline SVG.

Basically, I need the SVG to be sized to the "container" - the "container" is size to the browser window.

For an example of what works before I tried the whole div thing:

SVG Only Example - works perfectly

<html>
<body>
    <svg id="container" style="position:relative;border:dashed;width:100%;height:100%;" viewBox="0 0 1000 500">
        <svg id="background" name="Box" x="0" y="0">
            <rect width="1000" height="500" stroke="lime" fill="blue" stroke-width="10" />
            <svg id="shape" name="Triangle" x="275" y="50" fill="red" stroke="yellow" stroke-width="3">
                <path d="M0,378L185,0L371,378Z" />
            </svg>
        </svg>
    </svg>
</body>
</html>

But when I try to wrap divs around them, it just stays the same size as my viewBox, no matter what I've tried. I've looked up a lot on this on SO and elsewhere and nothing seems to work: padding tricks, 100vw, width, height, etc.

Here's the latest of what I've tried:

SVG wrapped in DIV Example - doesn't behave the same

<html>
<body>
    <div id="container" style="position:relative;border:dashed;width:100%;height:0;margin:5px">
        <div id="background" style="position:absolute;left:0px;top:0px;width:1000px;height:500px;">
            <svg name="Box" viewBox="0 0 1000 500">
                <rect width="1000" height="500" stroke="lime" fill="blue" stroke-width="10" />
            </svg>
            <div id="shape" style="position:absolute;left:275px;top:50px;width:371px;height:378px;">
                <svg name="Triangle" viewBox="0 0 371 378" fill="red" stroke="yellow" stroke-width="3">
                    <path d="M0,378L185,0L371,378Z" />
                </svg>
            </div>
        </div>
    </div>
</body>
</html>

I put a "border:dashed;" in the first div, just to make sure it is resizing with the browswer window and it is. It's just that everything inside that div doesn't change.

Any advice on how to get the "wrapped in div" strategy to match the "plain SVG" strategy?

More clarity: I guess what I'm saying is that "background" shape needs to be 1000w x 500h, relative to the "container" size. Any of it's children need to be absolutely positioned inside of that 1000w 500h and relative to it. The "container" size is the available space. So if if the browser window is 3000w x 2000h, then technically the "background" shape should be 3000w x 1500h (and the child shapes resize accordingly too - but the stay in their original relative position - relative to 1000w x 500h). If the window 800 w by 600 h, the "background" and child shapes shrink to fit that, relatively. Just like the SVG example.

It might be helpful to take the SVG example above, save it as an html file, launch locally and resize your browser up and down. That's what I'm to find help with, but divs don't seem to know how to handle this.

like image 798
Meihua Avatar asked Oct 16 '19 22:10

Meihua


People also ask

How do I get rid of extra space below SVG in div element?

If you're setting the height on your SVG, and you want the <a> tag to wrap around your SVG: add height: fit-content; to the <a> add display: block; to the SVG.

How do I scale SVG viewBox?

Just set the viewBox on your <svg> , and set one of height or width to auto . The browser will adjust it so that the overall aspect ratio matches the viewBox .

How do I fix SVG size?

❓ How can I resize a SVG image? First, you need to add a SVG image file: drag & drop your SVG image file or click inside the white area to choose a file. Then adjust resize settings, and click the "Resize" button. After the process completes, you can download your result file.

How do I get rid of SVG padding?

This is done using the attribute "preserveAspectRatio" and setting it to "none". Hopefully this helps some of your understanding of SVGs, as they're a really useful tool! Save this answer.


1 Answers

There's no real equivalent to viewBox property of SVG on DIV elements. The closest one would transform scale. So if you give your div containers a specific size in pixel without adjusting on resize, you're going to somewhat override the viewbox calculations.

That being said, if your div containers are resized with the window, then it can work. Also with minimal javascript you can get the same result as viewbox.

For the css only solution, you define your div containers so they are 100% the size of the window. The SVG viewbox is then still making the calculations. You'll need to define a preserveAspectRatio to have the same behavior as your SVG example. Like this:

html, body {
  width: 100%;
  height: 100%;
  padding: 0px;
  margin:0px;
  
}

* {
  box-sizing: border-box;
}
<div id="container" style="position:relative;border:dashed;width:100%;height:100%;">

   <svg name="Box" style="position:relative;width:100%;height:100%;" viewBox="0 0 1000 500" preserveAspectRatio="xMinYMin">
     <rect width="100%" height="100%" stroke="lime" fill="blue" stroke-width="10" />
   </svg>
   <div id="shape" style="position:absolute;left:0px;top:0px;height:100%;width:100%;">
     <svg style="position:relative;width:100%;height:100%;" viewBox="0 0 1000 500" preserveAspectRatio="xMinYMin">
       <svg id="shape" name="Triangle" x="275" y="50" width="371" height="378" fill="red" stroke="yellow" stroke-width="3">
         <path d="M0,378L185,0L371,378Z" />
       </svg>
     </svg>
   </div>
 </div>

For the javascript solution, you define the size on your div containers, and your svg can then be relative and not have the positioning info. And on resize you adjust the scale based on the innerWidth. Like this:

window.onload = window.onresize = calculateScale

function calculateScale() {
  var scaleFactor = innerWidth / 1000;
  document.getElementById('container').style.transform = `scale(${scaleFactor})`

}
html,
body {
  width: 100%;
  height: 100%;
  padding: 0px;
  margin: 0px;
}

* {
  box-sizing: border-box;
}
<div id="container" style="position:absolute;border:dashed;width:1000px;height:500px;transform-origin: left top">

  <svg name="Box" style="position:relative;width:100%;height:100%;">
     <rect width="100%" height="100%" stroke="lime" fill="blue" stroke-width="10" />
   </svg>
  <div id="shape" style="position:absolute;width: 371px;height: 378px;top: 50px;left: 275px;">

    <svg style="width: 100%; height: 100%" id="shape" name="Triangle" fill="red" stroke="yellow" stroke-width="3">
         <path d="M0,378L185,0L371,378Z" />
       
     </svg>
  </div>
</div>
like image 186
Julien Grégoire Avatar answered Oct 21 '22 17:10

Julien Grégoire