How to svg viewbox and coordinate system explained
- Step 1Separate the viewport from the viewBox in your head — The viewport is the box the SVG occupies on screen — controlled by
width/heightattributes or CSS. TheviewBoxis which slice of user-coordinate space is painted into that box. Two different concepts: one is about page layout, the other about the drawing's internal coordinates. - Step 2Read the four numbers as window origin + window size — For
viewBox="min-x min-y width height": the window's top-left corner is at user-space(min-x, min-y); the window iswidthuser units across andheighttall. Anything drawn outside that rectangle falls outside the visible window (and may be clipped, depending onoverflow). - Step 3Compute the scale factor — The browser scales user units to fit the viewport. If the viewport is 240px wide and the
viewBoxwidth is 24, each user unit becomes 10px. Astroke-width="1"line is then 10px thick. This is why changing theviewBoxwidth — not thewidthattribute — is what rescales stroke and detail. - Step 4Apply preserveAspectRatio when ratios differ — If the
viewBoxratio (width:height) doesn't equal the viewport ratio,preserveAspectRatiodecides:meetscales until the whole viewBox fits (letterboxing the extra space),slicescales until the viewport is filled (cropping the overflow), andnonestretches X and Y independently. The alignment keyword (xMidYMid, etc.) places the scaled content. - Step 5Fix a broken mapping by matching the viewBox to the content — Whitespace means the viewBox is bigger than the artwork; clipping means it's smaller or offset. The cure is to set the viewBox to the artwork's real bounds. JAD's ViewBox Fixer measures every element's coordinates, takes the min/max, and writes
viewBox="minX minY width height"pluspreserveAspectRatio="xMidYMid meet"for you. - Step 6Verify the scale behaves as expected — Drop the SVG into a resizable container with
width:100%. With a correct viewBox the artwork should fill its box edge-to-edge and keep its aspect ratio. If a 1-unit stroke looks too heavy or too thin, the viewBox width is the lever to adjust — not the pixelwidth.
The four viewBox numbers
viewBox="min-x min-y width height". All values are in user units, never pixels. The tool computes all four from your element coordinates.
| Position | Name | Meaning | Increase it → | Decrease it → |
|---|---|---|---|---|
| 1st | min-x | User-space X of the window's left edge | Pan the content left (window moves right) | Pan the content right |
| 2nd | min-y | User-space Y of the window's top edge | Pan the content up (window moves down) | Pan the content down |
| 3rd | width | Window width in user units | Zoom out horizontally (content shrinks) | Zoom in horizontally (content grows) |
| 4th | height | Window height in user units | Zoom out vertically | Zoom in vertically |
preserveAspectRatio at a glance
Format: <align> [meet|slice]. Default is xMidYMid meet. The ViewBox Fixer writes this default only when the SVG has none.
| Value | What it does | Use when |
|---|---|---|
xMidYMid meet | Scale to fit entirely, centre both axes, letterbox extra space | Default for icons and logos — nothing is cropped |
xMinYMin meet | Fit entirely, pin to top-left | Content should anchor top-left in an oversized box |
xMidYMid slice | Scale to fill, centre, crop the overflow | Background art that must cover the whole viewport |
none | Stretch X and Y independently to fill — aspect ratio NOT preserved | Decorative dividers/waves that should distort to width |
viewport vs viewBox — who controls what
The two are independent. Mixing them up is the root cause of most scaling bugs.
| Concern | Controlled by | Units |
|---|---|---|
| On-page size of the SVG element | width/height attributes or CSS | Pixels (or %, em, …) |
| Which slice of the drawing is shown | viewBox | User units |
| How a ratio mismatch is resolved | preserveAspectRatio | n/a (keyword) |
| User-unit → pixel scale | Ratio of viewport size to viewBox size | Derived |
Cookbook
Worked coordinate examples. Each shows how a given viewBox maps content into a viewport, and what the ViewBox Fixer would compute.
How min-x / min-y pan the content
Same artwork, two viewBoxes that differ only in origin. Shifting min-x/min-y moves the visible window across user space — the drawing appears to pan in the opposite direction.
Artwork: a 20×20 square drawn at user (10,10)→(30,30)
viewBox="0 0 40 40" → square sits centre-ish, margins all round
viewBox="10 10 20 20" → window starts at the square's top-left;
square fills the viewport exactly
The ViewBox Fixer computes the second one: minX=10, minY=10,
width=20, height=20.How viewBox width sets the scale, not the width attribute
A 24-unit icon shown in a 240px viewport. The user-unit→pixel scale is viewport/viewBox = 240/24 = 10. Halving the viewBox width (zoom in) doubles the apparent size; changing the width attribute only changes the on-page box.
viewBox="0 0 24 24" width="240" → scale 10×, stroke-width 1 = 10px
viewBox="0 0 12 24" width="240" → scale 20× across X (zoomed in,
right half of art clipped)
viewBox="0 0 24 24" width="120" → smaller on page, same 5× scale,
proportions identicalmeet vs slice on a square viewBox in a wide viewport
A square (1:1) viewBox shown in a 2:1 viewport. meet fits the square and leaves side bars; slice fills the width and crops top/bottom. Alignment decides where.
viewBox="0 0 100 100" viewport 400×200 (2:1)
xMidYMid meet → square scaled to 200×200, centred,
100px empty on each side
xMidYMid slice → square scaled to 400×400, centred,
top & bottom 100px cropped off
none → square stretched to 400×200 (distorted)Why your icon shows whitespace — viewBox too big
Artwork only spans 0→40 but the viewBox claims 0→100. The extra 60 units are empty, so at any size the icon looks small and off-centre. The fix is to crop the viewBox to the real bounds.
Drawn content bounds: 0,0 → 40,40 Declared: viewBox="0 0 100 100" → 60% of the box is empty ViewBox Fixer reads the element coords, computes 0,0→40,40: New viewBox = 0 0 40 40 Now the art fills its window.
Why your icon is clipped — viewBox too small or offset
Content extends to x=30 but the viewBox width is only 24, so the rightmost 6 units are outside the window and get clipped. Recomputing from real bounds restores the full drawing.
Drawn content bounds: 0,0 → 30,24 Declared: viewBox="0 0 24 24" → x 24→30 falls outside, clipped ViewBox Fixer computes the union of all element extents: New viewBox = 0 0 30 24 Nothing is clipped now.
Edge cases and what actually happens
viewBox width/height of zero disables rendering
InvalidPer the SVG spec, a viewBox with a width or height of 0 disables rendering of the element entirely — the SVG shows nothing. This happens if every measurable element collapses to a single point (e.g. a zero-radius circle). The ViewBox Fixer computes the box from real extents; if the content genuinely has no extent in one axis, the resulting 0 width/height is faithful but the SVG won't render — add geometry or padding.
Negative width or height in viewBox is an error
InvalidThe spec defines a negative width or height as an error. The fixer can't produce one for normal art (width = maxX − minX ≥ 0), but a hand-edited file with viewBox="0 0 -24 24" is invalid and most browsers refuse to render it. Negative min-x/min-y are perfectly legal, though — they just place the window origin to the left of / above the user-space zero point.
preserveAspectRatio='none' distorts the artwork
By designnone tells the browser to scale X and Y independently to fill the viewport, so a circle becomes an ellipse in a non-square box. That's intended for decorative dividers and full-width waves, never for icons. If your icons look squashed, check for an inherited preserveAspectRatio="none". The ViewBox Fixer preserves an existing value and only adds xMidYMid meet when none is set.
Percentage width/height interacts with the viewBox
ExpectedWith width="100%" the viewport size comes from the parent layout, and the viewBox still controls the internal scale. This is the correct responsive setup. Note the ViewBox Fixer's strip step only removes numeric/px width/height — a width="100%" is left in place, so you keep your responsive sizing while gaining a correct viewBox.
overflow controls whether out-of-box content clips
ExpectedBy default SVG content outside the viewBox is clipped (overflow:hidden on the root). If you've set overflow:visible, content beyond the box paints anyway — which can mask a wrong viewBox (you see everything, but the layout box is still wrong, breaking alignment and scaling). Fix the viewBox to match the content rather than relying on visible overflow.
Nested SVGs each have their own viewBox
SupportedAn inner <svg> establishes a new viewport and coordinate system. The ViewBox Fixer rewrites the root <svg> tag's attributes; nested <svg> elements keep their own viewBox. If a nested SVG is mis-sized, fix that file independently before nesting it.
Transforms move content out of the declared box
IgnoredA transform on a group can push content outside the viewBox window even though the raw coordinates look fine. Because the ViewBox Fixer ignores transforms, its computed box reflects pre-transform coordinates and may not match where the shape renders. Flatten transforms first for a box you can trust.
Stroke width extends beyond the geometric bounds
ApproximateA path's coordinates define its centre line; a thick stroke paints half its width outside those coordinates. The bounding box is geometric (centre-line based), so a heavy stroke can paint slightly outside the computed viewBox and get clipped at the edges. Add a few units of Padding in the fixer to give strokes room, or account for half the stroke width manually.
Very large coordinate values reduce precision
ExpectedSVG user units are floating point. Artwork drawn at coordinates in the millions (some CAD exports) loses sub-pixel precision and may render with visible jitter. A viewBox that frames such coordinates is valid but inherits the precision loss. Translate the artwork near the origin before fixing the viewBox for cleaner rendering.
Comma vs space separators in the viewBox string
SupportedThe spec allows the four numbers to be separated by spaces and/or commas (0 0 24 24 or 0,0,24,24). Browsers accept both. The ViewBox Fixer always writes space-separated values, which is the most widely compatible form and what every major design system uses.
Frequently asked questions
What's the difference between the viewport and the viewBox?
The viewport is the box the SVG occupies on the page, set by the width/height attributes or CSS, measured in pixels. The viewBox is which rectangle of the drawing's user-coordinate space is mapped into that viewport, measured in user units. The browser scales user units to pixels by the ratio of the two. They're independent: you can change one without the other.
What do the four viewBox numbers mean?
viewBox="min-x min-y width height". The first two are the user-space coordinates of the visible window's top-left corner; the last two are how many user units wide and tall the window is. Together they define the rectangle of the drawing that gets shown.
Are viewBox values in pixels?
No — they're in user units, an abstract coordinate space. The mapping to pixels happens via the viewport size. A viewBox="0 0 24 24" shown in a 480px-wide viewport renders each user unit as 20px. This decoupling is exactly what makes SVG resolution-independent.
How do I zoom or pan with the viewBox?
Pan by changing min-x/min-y (the window origin); zoom by changing width/height (smaller = zoomed in, larger = zoomed out). For example, viewBox="5 5 10 10" on 24-unit art zooms into the centre. The JAD ViewBox Fixer doesn't do interactive pan/zoom — it computes the tight box that frames everything.
What is preserveAspectRatio for?
It decides what happens when the viewBox's aspect ratio differs from the viewport's. meet fits the whole viewBox in (letterboxing the spare space); slice fills the viewport (cropping the overflow); none stretches X and Y independently. An alignment keyword like xMidYMid says where to place the scaled content. The recommended default for icons is xMidYMid meet.
Why does my SVG ignore its width and height attributes?
If CSS sets a width/height (or the SVG is inline with width:100%), CSS wins over the attributes — and the viewBox still governs the internal scale. That's normal. If the SVG has a viewBox and no fixed pixel size, it becomes fully responsive. The ViewBox Fixer leans into this by stripping pixel width/height so CSS can take over.
Can min-x and min-y be negative?
Yes. Negative min-x/min-y simply place the window origin to the left of or above user-space (0,0), which is common when artwork is centred on the origin (e.g. viewBox="-12 -12 24 24"). What's invalid is a negative width or height. The fixer can produce negative min-x/min-y when you add padding or when content sits in negative space.
How does the ViewBox Fixer compute the four numbers?
It parses the SVG, reads the coordinate attributes of every rect, circle, ellipse, line, polygon, polyline and path, finds the minimum and maximum X and Y across all of them, and sets min-x=minX, min-y=minY, width=maxX−minX, height=maxY−minY (plus any padding). It then formats each to at most two decimals.
Is the computed box always exact?
It's exact for straight-line geometry and absolute-coordinate paths. It's approximate for paths using curves (control points are counted), arcs (radii/flags get mis-read as coordinates), or relative commands (deltas read as absolutes), and it ignores transforms. In those cases treat the box as a close estimate — usually a safe over-estimate — and verify visually.
Why does a 0-width or 0-height viewBox show nothing?
The SVG spec says a viewBox with a zero width or height disables rendering of that element. If your content has no extent in one axis (a single horizontal line has zero height, for instance), the honest computed box has a zero dimension and the SVG won't paint. Add a little Padding in the fixer, or ensure the artwork has area in both axes.
Does the viewBox affect stroke thickness?
Indirectly, yes. Stroke width is in user units, then scaled to pixels by the viewport/viewBox ratio. A stroke-width="1" in a viewBox="0 0 24 24" displayed at 240px is 10px thick. Halving the viewBox width doubles the apparent stroke. So if strokes look wrong after a fix, the viewBox scale — not the stroke value — usually changed.
Where should I go after I understand the theory?
To apply it: run the file through this tool to set a correct viewBox, then the responsive wrapper to generate an aspect-ratio container for your page. For design-system consistency across an icon set, read the icon-consistency-standards guide. To tidy coordinate precision, use the precision tuner.
Privacy first
Every JAD SVG tool runs entirely in your browser using the DOM API and Canvas. Your SVG files never leave your device — verified by zero outbound network requests during processing.