snazzybouche
snazzybouche

Reputation: 2427

How do I scale and center an inline SVG?

I have a <div> container of variable width, and also a <svg> of variable size contained within it.

The div is variable because it is based on window size. The svg is variable because it is defined by user input.

I'd like to scale the SVG such that it is entirely visible within the containing div, without the div cropping the svg, or with excess whitespace. Is there a method to do this?

Thank you very much!

Example: https://jsfiddle.net/5zq0bhu7/1/

Upvotes: 0

Views: 896

Answers (1)

Scott
Scott

Reputation: 5369

What you're likely looking for is the viewBox property, which defines the bounds of your graphic and how it scales within its container. You can call svg.getBBox() to get the rough size of the internal paths of the SVG.

Here is the result:

var svg = document.querySelector("svg");

// Get internal size of SVG
var bbox = svg.getBBox();

// Construct and set a viewBox for the SVG
var viewBox = [bbox.x, bbox.y, bbox.width, bbox.height].join(" ");

svg.setAttribute("viewBox", viewBox);
<div id="drawing" style="border: 1px solid black; width: 200px; height: 200px;">
    <!-- width and height will vary in the application, but are defined here for debugging purposes -->
    <svg xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" preserveAspectRatio="none">
        <g fill="none" stroke="#000">
            <path stroke-width=".26458" d="M8.134 1.4a13.23 13.23 0 0 1 10.006 0M12.852.417a.285.285 0 1 1 .57 0 .285.285 0 1 1-.57 0M22.4 4.202a13.23 13.23 0 0 1 3.964 9.188M20.13 6.882a3.44 3.44 0 1 1 2.725 6.32 3.44 3.44 0 1 1-2.726-6.32m6.234 6.508" />
            <path stroke-width=".26458" d="M25.81 17.44a13.23 13.23 0 0 1-.017.057 6.216 6.216 0 1 0-8.076 8.56 13.23 13.23 0 0 1-.056.02M23.64 22.7a.622.622 0 1 1-.853.903.622.622 0 1 1 .853-.904m-5.977 3.378" />
            <path stroke-width=".26458" d="M12.624 26.866a13.23 13.23 0 0 1-.058-.003A6.216 6.216 0 1 0 2.26 21.177a13.23 13.23 0 0 1-.033-.048" />
            <path stroke-width=".26458" d="M.208 16.447a13.23 13.23 0 0 1-.013-.057A6.216 6.216 0 1 0 3.13 4.992a13.23 13.23 0 0 1 .04-.044" />
        </g>
    </svg>
</div>

It's entirely visible in the container, and does not get cropped. Excess whitespace is aggressively scaled off. Here's a quick rundown of each property that is set:

  • viewBox to control the container scaling, dynamically generated with the call to getBBox()
  • width and height to force the graphic to fill its container
  • preserveAspectRatio to none to allow the SVG to scale to fit any container - remove this property to enforce the same aspect ratio - the SVG will instead fill the largest available dimension by default.

Upvotes: 2

Related Questions