SVG viewBox Explained: The Complete Guide to Scaling Vector Graphics
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
- Right-click the SVG → Inspect
- Look at the
viewBoxattribute - Check computed width/height
- 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
- viewBox defines the internal coordinate system — it's like a window into your SVG scene
- Content scales to fill the viewBox — whatever's inside gets stretched or shrunk to fit
- Aspect ratio mismatches cause issues — use
preserveAspectRatioto control fitting behavior - For responsive SVGs, combine viewBox with CSS — let the container control size, viewBox controls proportions
- 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.