PerfectVector
By Irene Kim9 min read

SVG preserveAspectRatio: Fit Artwork Without Stretching

Choose meet, slice, or none for SVG fitting. Test alignment, clipping, and empty canvas with one emblem, and separate SVG mapping from CSS object-fit.

On this page

Use preserveAspectRatio="xMidYMid meet" when the whole SVG viewBox should fit inside its display area without stretching. Use slice when that area must be covered and some content can extend beyond its edges. Use none only when unequal horizontal and vertical scaling is intentional.

The important distinction is between the artwork's coordinate rectangle, defined by viewBox, and the viewport where it appears. Fitting changes how one maps into the other. It does not redraw a logo, remove empty source canvas, or permanently delete cropped paths.

Choose the fitting behavior first

GoalAttribute valueTradeoff when the ratios differ
Show the entire viewBoxxMidYMid meetUnused space remains along one axis
Cover the viewportxMidYMid slicePart of the viewBox extends outside the viewport
Fill using independent axis scalesnoneCircles and other proportions can distort

MDN's preserveAspectRatio reference documents these values and the default, xMidYMid meet. For an svg element, this mapping requires a viewBox. The attribute is case-sensitive: preserve the capital A and R.

For a logo, start with meet. Losing a letter or changing a circle into an oval is usually a worse result than leaving some space. For an ornamental background, a deliberate crop may be acceptable. Decide that before choosing alignment.

Conceptual comparison of a complete emblem, a cropped enlarged emblem, and a stretched emblem inside frames
Illustration of three fitting choices: preserve the full composition, cover the frame with a crop, or allow distortion. The browser measurements below use a separate original SVG fixture.

Test one emblem in two viewport shapes

This original example uses a circle, a rectangle, and an off-center triangle. The circle makes stretching visible; the unequal parts make alignment changes easier to notice than they would be in a symmetric badge.

Paste this into an HTML file and open it in a browser:

<svg width="300" height="100" viewBox="0 0 200 100"
     preserveAspectRatio="xMidYMid meet"
     xmlns="http://www.w3.org/2000/svg"
     role="img" aria-label="Circle, rectangle, and triangle emblem"
     style="background:#f4ead4; overflow:hidden">
  <circle cx="40" cy="50" r="25" fill="#147d78" />
  <path d="M85 20 H130 V80 H85Z" fill="#e5a340" />
  <path d="M145 70 L170 25 L190 70Z" fill="#183549" />
</svg>

The viewBox is 200 units wide and 100 units tall. Its ratio is 2:1. The first viewport is 300 by 100 CSS pixels, a 3:1 ratio. Change only the attribute to compare xMidYMid slice and none. Then change the viewport to width="100" height="300" and repeat.

We rendered this geometry in Chrome with a small selector-based harness. Its readout used the artwork group's current transformation matrix. The resulting scales and translations matched these values; the slice offset of approximately −25 pixels is rounded here.

ViewportSettingHorizontal / vertical scaleCentered translation in viewport pixels
300 × 100meet1 / 150 horizontally, 0 vertically
300 × 100slice1.5 / 1.50 horizontally, −25 vertically
300 × 100none1.5 / 10 / 0
100 × 300meet0.5 / 0.50 horizontally, 125 vertically
100 × 300slice3 / 3−250 horizontally, 0 vertically
100 × 300none0.5 / 30 / 0

In the tall viewport, meet showed all three small shapes. Centered slice showed only part of the enlarged composition, dominated by the gold rectangle. none made the circle narrow and tall. This is a check of this fixture in Chrome, not a promise about every graphics editor's import behavior.

The scale rule is straightforward for this zero-origin example. Divide viewport width by viewBox width, then viewport height by viewBox height. meet uses the smaller ratio for both axes; slice uses the larger. none keeps the two ratios separate. The SVG coordinate-system specification defines the mapping, including alignment and nonzero viewBox origins.

Use alignment to choose where the spare space goes

The first keyword controls alignment. xMin, xMid, and xMax align the viewBox's left edge, horizontal center, or right edge. YMin, YMid, and YMax do the equivalent vertically. These refer to the viewBox rectangle, which may contain empty space around the actual paths.

For the tall test viewport:

  • xMinYMin meet places the fitted viewBox at the top instead of centering it vertically.
  • xMinYMin slice keeps the viewBox's left side aligned with the viewport's left side. The enlarged right side extends beyond the viewport.
  • xMidYMid slice distributes the horizontal overflow on both sides.

We changed the harness from centered to xMinYMin. Both the meet and slice translations became zero, while their scale factors stayed at 0.5 and 3 respectively. Alignment moved the composition; it did not change the fitting scale.

An alignment change is visible only on an axis with spare space or overflow. In the wide meet case, the viewBox already fills the height, so changing YMid to YMin has no vertical room to move it.

Make clipping an explicit choice

slice selects a scale. Clipping determines whether you can see the parts that extend outside the viewport. The example sets overflow:hidden explicitly so the crop is predictable.

In the tall harness, switching overflow to visible revealed the enlarged circle and triangle beyond the slice viewport. The geometry had not disappeared. MDN's SVG overflow reference explains the relationship between overflow and viewport clipping, including differences in default styling between SVG contexts.

Avoid treating slice as a path-trimming operation. If a delivery file must contain only the retained geometry, perform and verify an actual editing operation. For a custom nonrectangular display window, a clipPath may be the appropriate tool instead.

Likewise, meet guarantees the viewBox fits; it cannot guarantee that all painted content fits. A stroke, filter, or path outside that source rectangle can still extend beyond it. Inspect the visible edges rather than trusting the attribute alone.

Fix source whitespace before fighting alignment

Suppose a small mark occupies only the middle of a very large viewBox. meet fits that entire coordinate rectangle, including its empty margins. The result can look too small even when the scaling is correct.

Check the exported canvas or artboard in your editor. If you change the viewBox to tighten the composition, include the intended strokes and effects and recheck each placement. Do not remove every margin automatically: the source may contain deliberate clear space around a brand mark.

Physical-size problems are separate. An SVG that imports at the wrong millimeter size needs the SVG sizing workflow; changing fit alignment is unlikely to fix its unit assumptions.

Keep inline SVG and image fitting separate

For inline SVG, change the attribute on the relevant svg element. CSS can size that element's box, while preserveAspectRatio maps its viewBox into that box.

For an external SVG used in an HTML image element, CSS controls the replaced image's fit:

<img class="brand-mark" src="emblem.svg" alt="Brand emblem">
<style>
  .brand-mark {
    width: 300px;
    height: 100px;
    object-fit: contain;
    object-position: center;
  }
</style>

MDN's object-fit documentation describes how replaced content fits its CSS box. That is a different layer from editing the SVG document's internal mapping. object-fit: contain also cannot remove blank canvas already present in the source. See inline SVG versus an image element when deciding which embedding model to use.

There is also an SVG image element, spelled with the full word rather than HTML's img. Its preserveAspectRatio controls how the referenced image fits the rectangle established for that element. It is the exception to the general requirement to supply a viewBox on the same element, as the MDN attribute reference explains. Keeping these three cases separate avoids trying to fix an HTML image by adding an SVG-only attribute to it.

Preserve the source proportions before placement

If you only have a PNG or JPG of your custom mark and need editable vector geometry, PerfectVector can recover an SVG source before you build the layout. Inspect the contours, small openings, and canvas bounds first. Fitting the result preserves its current geometry; it cannot repair a distorted source or recreate detail that was never recovered.

An existing clean SVG can go directly to the fitting checks. For the simple emblem above, hand-authored geometry is sufficient. The image-vectorization overview explains when recovering paths from a raster image is useful.

For a raster-only mark, try your source in PerfectVector, inspect the SVG, then compare a wide and a tall placement with meet before considering a crop. Keep the original vector master so layout decisions remain reversible.

FAQ

Why does my SVG still have empty space with meet? The viewport and viewBox may have different aspect ratios, leaving spare space after uniform scaling. The source viewBox may also contain margins around the paths. Alignment moves that rectangle; it does not remove its internal whitespace.

Does slice permanently crop the artwork? No. It changes the scale used to cover the viewport. Overflow and clipping control which parts are visible. The original path geometry remains in the document unless you edit it separately.

Why does none turn my circle into an oval? It allows different horizontal and vertical scale factors. When the viewport and viewBox ratios differ, a circle can become an ellipse. Use meet or slice with an alignment keyword to keep uniform scaling.

Sources

  1. MDN preserveAspectRatio — Defines fitting values, alignment, defaults, and the SVG image exception.
  2. SVG coordinate-system specification — Defines the scale and translation calculation for a viewport.
  3. MDN SVG overflow — Explains how overflow controls viewport clipping.
  4. MDN object-fit — Documents fitting replaced image content within a CSS box.

More from the blog

Start with a cleaner SVG
that is easier to edit