SVG Fill Width to Child Elements

2019-07-17 17:39发布

问题:

I'd like my container SVG element to scale in order to fit its child group elements or for it to present scrollbars on overflow. I was wondering if there was a css property in order to do so.

E.g. If the markup looks like the following:

<div class="wrapper" style="width:500px; overflow-x:scroll;">
   <svg class="main">
      <g width="1000"></g>
   </svg>
</div>

How might I get the svg's width to fill to '1000' or present scrollbars if child elements exceed its width?

The following css has no effect on the above:

.main {
    width: 500px; // Setting to 100% also does nothing
    overflow-x: scroll;
}

I currently achieve the desired effect with javascript by updating the svg container's width as necessary; but this is cumbersome and error-prone, as I'd need to check to make sure that when any new element is added inside svg, that the svg container resizes to fit.

Any help would be much appreciated.

回答1:

Not sure if this solves your problem or not, but you could put the constraints on svg's parent tag (the div tag).

Something like this:

<div class="wrapper">
  <svg class="main" xmlns="http://www.w3.org/2000/svg">
    <g>
      <rect x="20" y="20" height="250" width="400" style="fill:#006600"/>       
    </g>
  </svg>
</div>

.wrapper {
    width: 200px;
    height: 100px;
    overflow: scroll;
}
.main {
    width: 400px; 
    height: 250px;
}

Here's a jsfiddle.



回答2:

remove width and height from the <svg> and add an viewBox attribute instead. Addionally you need a preserveAspectRatio attribute with a value of your desired behavior.

For more detailed information have a look here. This method uses the SVG viewport which is a bit complicated at the first glance, but in effect, this separates the visible dimensions from the graphical setup of the graphic. This way the <svg> receives its width and height from the context it lives in, from the css in your case.

It took me a while to understand that concept, but once you got it you will notice that gives you a lot flexibility, what is actually much more than with pixel images.



回答3:

There is no way to have the SVG automatically update its width and height when you add elements to it. All you can do is manually update the width and height yourself.

However, rather than having to remember to update the SVG width and height every time you add something, you could add an interval timer function to do the check for you.

setInterval(mySVGCheckFn, 500);

function  mySVGCheckFn() 
{
    var  svg = document.getElementById("mysvg");
    var  bbox = svg.getBBox();

    // Add 10 padding for some breathing space    
    svg.setAttribute("width", bbox.x + bbox.width + 10);
    svg.setAttribute("height", bbox.y + bbox.height + 10);
}

Demo here

Click 'Add more' to add random circles to the SVG.

DOM2 added some event types that are supposed to be fired when you add nodes to the DOM. They would be the ideal solution, however I believe they aren't supported reliably across all browsers.