Home > Software design >  Scale element to pixel size
Scale element to pixel size

Time:03-31

I have an SVG element of dynamic size. I want to scale it and its contents to a particular pixel size (not by pixels) on demand.

This is invalid:

transform: scale(100px);

My knowledge of SVG is middling so maybe there's a better way, but setting the height/width of the SVG element after the contents are drawn simply causes its contents to runeth over, as they are "absolute" and not "relative" paths.

With JS you can just get the relative sizes:

const scaleX = targetWidth / svg.offsetWidth;
const scaleY = targetHeight / svg.offsetHeight;
svg.style.scale = `${scaleX}px ${scaleY}px`; //untested but you get the idea

My hope is there is a sort of "scaleTo" somewhere in CSS3 I'm unaware of, or neat trick to accomplish this. An authoritative "no" is an acceptable answer.

CodePudding user response:

If you have access to the html for the svg, you can remove the svg element's width and height attributes and replace them with a viewBox attribute of the with the x/y positions set to 0, and the width/height pair set to the values you deleted:

<svg width="300" height="200">
<!-- change to: -->
<svg viewBox="0 0 300 200">

You can then place the svg element inside a sized div and set the css width and height of the svg to 100%:

    .svgContainer svg {
      width: 100%;
      height: 100%;
    }

See working snippet to compare effects, I've squeezed the same svg into a smaller div, with and without the viewBox set.

Note for a dynamic resize, the div container has to resize dynamically, the viewBox version of the svg set to 100% width and height of the container will take care of itself. If the container Div had been sized by % instead of pixels, it will grow and shrink with the viewport of the browser.

If you can't access the html markup, you could achieve the same by retrieving the width and height attributes of the svg using javascript and set a new attribute for the viewBox.

More about viewBox: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox

.svgContainer {
  width: 100px;
}

.svgContainer svg {
  margin: 0;
  width: 100%;
  height: 100%;
}
<p> 300x200 svg rendered outside of a container:</p>
<svg width="300px" height="200px">
<rect x="0" y="0" width="100%" height="100%" fill="red" stroke="blue"/>
<rect x="100" y="50" width="100" height="50" fill="yellow"/>
<rect x="30" y="20" width="20" height="35" fill="blue"/>
</svg>

<p> same 300x200 svg rendered inside sized div:</p>
<div >
<svg width="300px" height="200px">
<rect x="0" y="0" width="100%" height="100%" fill="red" stroke="blue"/>
<rect x="100" y="50" width="100" height="50" fill="yellow"/>
<rect x="30" y="20" width="20" height="35" fill="blue"/>
</svg>
</div>

<p>svg modified to use viewbox attribute values, inside sized div</p>
<div >
<svg viewBox="0 0 300 200">
<rect x="0" y="0" width="100%" height="100%" fill="red" stroke="blue"/>
<rect x="100" y="50" width="100" height="50" fill="yellow"/>
<rect x="30" y="20" width="20" height="35" fill="blue"/>
</svg>
</div>

  • Related