Back to BlogTechnical

SVG viewBox Explained: The Complete Guide to Scaling Vector Graphics

SVG Genie Team12 min read

Your SVG looks perfect in Figma. You export it, drop it into your HTML, and... it's cropped. Or stretched. Or tiny. Or massive.

The culprit is almost always viewBox.

viewBox is the most misunderstood SVG attribute. Once you understand it, you'll never have scaling issues again. This guide explains exactly how it works.

What Is viewBox?

The viewBox attribute defines the coordinate system inside the SVG.

<svg viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40"/>
</svg>

That viewBox="0 0 100 100" means:

  • The internal coordinate space starts at (0, 0)
  • It extends 100 units wide and 100 units tall
  • Everything inside uses this coordinate system

Think of it like a window:

  • viewBox defines what you're looking at (the scene)
  • width/height define the size of the window on your screen

The magic: whatever fits in the viewBox gets scaled to fill whatever size you set with width/height.

viewBox Syntax

viewBox="min-x min-y width height"

| Parameter | Meaning | |-----------|---------| | min-x | Left edge of the visible area | | min-y | Top edge of the visible area | | width | Width of the visible area | | height | Height of the visible area |

Common viewBox values:

<!-- Standard square -->
<svg viewBox="0 0 100 100">

<!-- Rectangle (wider than tall) -->
<svg viewBox="0 0 200 100">

<!-- Starting from negative coordinates -->
<svg viewBox="-50 -50 100 100">

<!-- Common icon size -->
<svg viewBox="0 0 24 24">

How viewBox Scaling Works

Example 1: Basic Scaling

<!-- SVG with 100x100 viewBox, displayed at 200x200 pixels -->
<svg viewBox="0 0 100 100" width="200" height="200">
  <circle cx="50" cy="50" r="40"/>
</svg>

The circle is defined at coordinates (50, 50) with radius 40 in viewBox units. When rendered at 200x200 pixels, everything scales 2x:

  • Circle center: (100, 100) in pixels
  • Circle radius: 80 pixels

Example 2: Scaling to Any Size

The same viewBox renders identically at any size:

<!-- Tiny -->
<svg viewBox="0 0 100 100" width="20" height="20">
  <circle cx="50" cy="50" r="40"/>
</svg>

<!-- Medium -->
<svg viewBox="0 0 100 100" width="100" height="100">
  <circle cx="50" cy="50" r="40"/>
</svg>

<!-- Huge -->
<svg viewBox="0 0 100 100" width="500" height="500">
  <circle cx="50" cy="50" r="40"/>
</svg>

Same circle, same proportions, three different sizes. That's the power of viewBox.

Example 3: Zooming with viewBox

Changing the viewBox values zooms the view:

<!-- Full view -->
<svg viewBox="0 0 100 100" width="200" height="200">
  <circle cx="50" cy="50" r="40"/>
</svg>

<!-- Zoomed in (showing only the center quarter) -->
<svg viewBox="25 25 50 50" width="200" height="200">
  <circle cx="50" cy="50" r="40"/>
</svg>

By setting viewBox to "25 25 50 50", we're looking at a smaller portion of the scene—effectively zooming in 2x.

viewBox vs width/height

Without viewBox:

<svg width="200" height="200">
  <circle cx="50" cy="50" r="40"/>
</svg>

The circle renders at exactly 50,50 with radius 40 pixels. Change width/height and the circle stays the same size—you just see more or less empty space.

With viewBox:

<svg viewBox="0 0 100 100" width="200" height="200">
  <circle cx="50" cy="50" r="40"/>
</svg>

The 100x100 viewBox scales to fit the 200x200 pixel dimensions. The circle scales proportionally.

Key insight: viewBox creates a scalable coordinate system. Width/height without viewBox creates a fixed pixel canvas.

Common viewBox Problems (and Fixes)

Problem 1: SVG Is Cropped

Symptom: Parts of your graphic are cut off.

Cause: The viewBox is too small for the content.

<!-- Content extends beyond viewBox -->
<svg viewBox="0 0 50 50">
  <circle cx="50" cy="50" r="40"/>  <!-- Center at edge! -->
</svg>

Fix: Expand viewBox to contain all content:

<svg viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40"/>
</svg>

How to find correct viewBox: Use SVG Editor or browser DevTools to inspect the bounding box of your content.

Problem 2: SVG Has Unexpected Padding

Symptom: Lots of empty space around your graphic.

Cause: viewBox is larger than necessary.

<!-- viewBox much larger than content -->
<svg viewBox="0 0 1000 1000">
  <circle cx="50" cy="50" r="40"/>  <!-- Tiny in corner -->
</svg>

Fix: Shrink viewBox to match content:

<svg viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40"/>
</svg>

Problem 3: SVG Is Stretched/Squished

Symptom: Circles look like ovals, squares look like rectangles.

Cause: viewBox aspect ratio doesn't match container aspect ratio.

<!-- Square viewBox in rectangular container -->
<svg viewBox="0 0 100 100" width="200" height="100">
  <circle cx="50" cy="50" r="40"/>
</svg>

Fix: Either match aspect ratios or use preserveAspectRatio (covered below).

Problem 4: SVG Won't Scale

Symptom: SVG stays the same size regardless of container.

Cause: Using width/height without viewBox, or using fixed units.

<!-- Won't scale - no viewBox -->
<svg width="100px" height="100px">
  <circle cx="50" cy="50" r="40"/>
</svg>

Fix: Add viewBox and use relative sizing:

<svg viewBox="0 0 100 100" width="100%" height="auto">
  <circle cx="50" cy="50" r="40"/>
</svg>

preserveAspectRatio: Controlling Fit

When viewBox aspect ratio doesn't match the SVG's width/height, preserveAspectRatio controls how content fits.

Syntax

preserveAspectRatio="<align> [<meetOrSlice>]"

Alignment Options

xMinYMin  xMidYMin  xMaxYMin
xMinYMid  xMidYMid  xMaxYMid
xMinYMax  xMidYMax  xMaxYMax
  • xMin — Align to left
  • xMid — Center horizontally
  • xMax — Align to right
  • YMin — Align to top
  • YMid — Center vertically
  • YMax — Align to bottom

Meet vs Slice

  • meet (default) — Scale uniformly to fit entirely within container (letterboxing)
  • slice — Scale uniformly to fill container completely (cropping)

Examples

<!-- Center and fit inside (default) -->
<svg viewBox="0 0 100 100" width="200" height="100"
     preserveAspectRatio="xMidYMid meet">

<!-- Center and fill, cropping excess -->
<svg viewBox="0 0 100 100" width="200" height="100"
     preserveAspectRatio="xMidYMid slice">

<!-- Top-left, fit inside -->
<svg viewBox="0 0 100 100" width="200" height="100"
     preserveAspectRatio="xMinYMin meet">

<!-- Stretch to fill (ignore aspect ratio) -->
<svg viewBox="0 0 100 100" width="200" height="100"
     preserveAspectRatio="none">

preserveAspectRatio="none" stretches the graphic to fill the container. Use sparingly—it distorts your graphics.

Visual Guide

| preserveAspectRatio | Behavior | |---------------------|----------| | xMidYMid meet | Centered, fits inside, may have letterboxing | | xMidYMid slice | Centered, fills container, may crop edges | | xMinYMin meet | Top-left aligned, fits inside | | none | Stretches to fill, distorts content |

Making SVGs Responsive

Method 1: Percentage Width, Auto Height

<svg viewBox="0 0 100 100" width="100%" height="auto">
  <!-- Content -->
</svg>

Problem: Many browsers don't calculate height properly from viewBox.

Method 2: Remove width/height, Use CSS

<svg viewBox="0 0 100 100" class="responsive-svg">
  <!-- Content -->
</svg>
.responsive-svg {
  width: 100%;
  height: auto;
}

Method 3: Aspect Ratio Container (Bulletproof)

<div class="svg-container">
  <svg viewBox="0 0 100 100">
    <!-- Content -->
  </svg>
</div>
.svg-container {
  position: relative;
  width: 100%;
  padding-bottom: 100%; /* 1:1 aspect ratio */
}

.svg-container svg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

For a 16:9 SVG, use padding-bottom: 56.25% (9/16 = 0.5625).

Method 4: CSS aspect-ratio (Modern)

.responsive-svg {
  width: 100%;
  aspect-ratio: 1 / 1; /* Matches viewBox aspect ratio */
}

Supported in all modern browsers. Simplest solution if you don't need legacy support.

Learn more in our Complete SVG Guide and SVG vs PNG vs JPG.

viewBox in Practice

Icon Systems

Icons typically use consistent viewBox values:

<!-- Standard 24x24 icon grid -->
<svg viewBox="0 0 24 24">
  <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5"/>
</svg>

Keeping viewBox consistent makes icons interchangeable and styling predictable.

See Adaptive SVGs with CSS Custom Properties for advanced icon system techniques.

Logos

Logos need precise viewBox values matching their bounding box:

<!-- Logo with exact viewBox -->
<svg viewBox="0 0 340 80">
  <!-- Logo paths -->
</svg>

Export from design tools typically sets correct viewBox automatically.

Illustrations

Complex illustrations may use larger viewBox values for more coordinate precision:

<svg viewBox="0 0 1000 800">
  <!-- Complex illustration with many elements -->
</svg>

Larger numbers allow more detailed positioning without fractional values.

Data Visualization

Charts often use viewBox with dynamic content:

// D3.js example
const svg = d3.select("svg")
  .attr("viewBox", `0 0 ${width} ${height}`);

Debugging viewBox Issues

Browser DevTools

  1. Right-click the SVG → Inspect
  2. Look at the viewBox attribute
  3. Check computed width/height
  4. Temporarily add a background to see actual SVG bounds:
svg { background: rgba(255, 0, 0, 0.1); }

Common Debug Techniques

Add a border rectangle:

<svg viewBox="0 0 100 100">
  <!-- Debug: shows viewBox bounds -->
  <rect x="0" y="0" width="100" height="100"
        fill="none" stroke="red" stroke-width="0.5"/>

  <!-- Your actual content -->
  <circle cx="50" cy="50" r="40"/>
</svg>

Check if content exceeds viewBox:

const svg = document.querySelector('svg');
const bbox = svg.getBBox();
console.log('Content bounds:', bbox);
// Compare with viewBox values

Tools for viewBox Management

Automatic viewBox Calculation

SVG Genie generates SVGs with correct viewBox values automatically. The AI calculates appropriate bounds for whatever graphic it creates, so you don't have to adjust viewBox manually.

Manual Adjustment Tools

  • SVG Editor — Visual viewBox adjustment
  • SVG Minify — Optimizes and can recalculate viewBox
  • SVGO — Command-line viewBox optimization with --enable=removeViewBox

Calculating viewBox from Content

If your SVG has wrong viewBox:

// Get actual content bounds
const svg = document.querySelector('svg');
const bbox = svg.getBBox();

// Calculate optimal viewBox
const padding = 10; // Optional padding
const viewBox = `${bbox.x - padding} ${bbox.y - padding} ${bbox.width + padding * 2} ${bbox.height + padding * 2}`;

svg.setAttribute('viewBox', viewBox);

Key Takeaways

  1. viewBox defines the internal coordinate system — it's like a window into your SVG scene
  2. Content scales to fill the viewBox — whatever's inside gets stretched or shrunk to fit
  3. Aspect ratio mismatches cause issues — use preserveAspectRatio to control fitting behavior
  4. For responsive SVGs, combine viewBox with CSS — let the container control size, viewBox controls proportions
  5. Debug with visible bounds — add temporary rectangles or backgrounds to see actual viewBox area

Master viewBox and you'll never fight with SVG scaling again. It's the key to truly scalable vector graphics.

Need perfectly-sized SVGs? SVG Genie generates graphics with correct viewBox values built in—no manual adjustment required.


Related Articles:

Create your own SVG graphics with AI

Describe what you need, get a production-ready vector in seconds. No design skills required.

Try SVG Genie Free

Ready to create your own vectors?

Start designing with AI-powered precision today.

Get Started Free