DevToolBoxGRATIS
Blogg

SVG viewBox forklart: Bredde, høyde, skalering og responsive SVGer

7 min lesningby DevToolBox

The SVG viewBox attribute is one of the most powerful — and most misunderstood — features of SVG. It controls the internal coordinate system, enables responsive scaling, and determines how your graphics zoom, pan, and fit within their container. This guide explains everything you need to know about viewBox, width, height, and responsive SVG patterns.

1. viewBox Syntax: min-x min-y width height

The viewBox attribute takes four numbers separated by spaces or commas: viewBox="min-x min-y width height". These define the rectangle of the SVG coordinate system that should be visible.

min-x, min-y: The top-left corner of the visible area in SVG coordinates. Usually 0 0, but changing these values lets you pan the view.

width, height: The size of the visible area in SVG coordinates. This does NOT set the pixel size of the SVG element — it defines how many coordinate units are visible.

<!-- viewBox syntax -->
<svg viewBox="0 0 200 100" width="400" height="200">
  <!-- min-x=0  min-y=0  width=200  height=100 -->
  <!-- The SVG coordinate system goes from (0,0) to (200,100) -->
  <rect x="10" y="10" width="80" height="80" fill="#3b82f6" />
  <circle cx="150" cy="50" r="40" fill="#ef4444" />
</svg>

Think of viewBox as a camera looking at your SVG canvas. The four values define where the camera is pointed and how wide its field of view is.

2. viewBox vs width/height: The Coordinate System

There are two separate sizing concepts in SVG that are often confused:

width and height attributes: Set the actual rendered size of the SVG element in the page (in pixels, ems, percentages, etc.). These are like the size of the TV screen.

viewBox: Defines the internal coordinate system — the "world" that the SVG content lives in. This is like the scene being filmed by the camera.

<!-- width/height = rendered size, viewBox = coordinate system -->

<!-- 200x200 pixel SVG, but internal coords go from 0-100 -->
<svg width="200" height="200" viewBox="0 0 100 100">
  <!-- x=50 means the horizontal center of the coordinate space -->
  <!-- Rendered at 100px from the left (50 * 200/100) -->
  <circle cx="50" cy="50" r="40" fill="#8b5cf6" />
</svg>

<!-- Same viewBox, but rendered at 400x400 pixels -->
<svg width="400" height="400" viewBox="0 0 100 100">
  <!-- Same circle, but now rendered twice as large -->
  <circle cx="50" cy="50" r="40" fill="#8b5cf6" />
</svg>

When both are set, the browser maps the viewBox coordinates onto the width/height area. If the aspect ratios differ, preserveAspectRatio controls how the content is fitted.

When only viewBox is set (no width/height), the SVG becomes responsive and fills its container while maintaining aspect ratio.

3. Visual Examples: Zooming In/Out, Panning

Default view — The viewBox matches the content area. All elements are visible at their natural size.

<!-- Default: viewBox matches content -->
<svg width="200" height="200" viewBox="0 0 200 200">
  <circle cx="100" cy="100" r="80" fill="#3b82f6" />
</svg>

Zooming in — A smaller viewBox crops the view, making elements appear larger. Reducing viewBox width/height "zooms in" because fewer coordinate units fill the same screen space.

<!-- Zoom in: smaller viewBox = magnified view -->
<svg width="200" height="200" viewBox="50 50 100 100">
  <!-- Only the center 100x100 area is visible -->
  <!-- The circle appears twice as large -->
  <circle cx="100" cy="100" r="80" fill="#3b82f6" />
</svg>

Zooming out — A larger viewBox shows more of the coordinate space, making elements appear smaller.

<!-- Zoom out: larger viewBox = wider view -->
<svg width="200" height="200" viewBox="-100 -100 400 400">
  <!-- 400x400 coordinate units squeezed into 200x200 pixels -->
  <!-- The circle appears half its default size -->
  <circle cx="100" cy="100" r="80" fill="#3b82f6" />
</svg>

Panning — Changing min-x and min-y shifts which part of the coordinate space is visible, like sliding a camera.

<!-- Pan: shift min-x and min-y -->
<svg width="200" height="200" viewBox="80 80 200 200">
  <!-- View shifted 80 units right and 80 units down -->
  <!-- The circle appears in the top-left corner -->
  <circle cx="100" cy="100" r="80" fill="#3b82f6" />
</svg>

4. preserveAspectRatio: meet vs slice, xMidYMid

When the viewBox aspect ratio does not match the SVG element's aspect ratio, preserveAspectRatio controls how the content is fitted. The syntax is: preserveAspectRatio="<align> <meetOrSlice>".

Alignment values control where the viewBox is positioned within the viewport. The format is xMinYMin, xMidYMid, xMaxYMax, etc. — combining horizontal (xMin, xMid, xMax) and vertical (YMin, YMid, YMax) alignment.

ValueBehaviorCSS Equivalent
xMidYMid meetCentered, fully visible (default)object-fit: contain
xMidYMid sliceCentered, fully coveredobject-fit: cover
xMinYMin meetTop-left aligned, containedobject-fit: contain; object-position: top left
xMaxYMax meetBottom-right aligned, containedobject-fit: contain; object-position: bottom right
noneStretch to fill, may distortobject-fit: fill

meet (default): Scale the viewBox to fit entirely inside the viewport. Similar to CSS background-size: contain. The entire content is visible, but there may be empty space.

slice: Scale the viewBox to cover the entire viewport. Similar to CSS background-size: cover. The viewport is completely filled, but some content may be cropped.

none: No uniform scaling. The viewBox stretches to fill the viewport exactly. Content may appear distorted.

<!-- meet: contain the content (default) -->
<svg width="400" height="200" viewBox="0 0 100 100"
     preserveAspectRatio="xMidYMid meet">
  <circle cx="50" cy="50" r="45" fill="#3b82f6" />
</svg>

<!-- slice: cover the viewport, crop overflow -->
<svg width="400" height="200" viewBox="0 0 100 100"
     preserveAspectRatio="xMidYMid slice">
  <circle cx="50" cy="50" r="45" fill="#ef4444" />
</svg>

<!-- none: stretch to fill exactly -->
<svg width="400" height="200" viewBox="0 0 100 100"
     preserveAspectRatio="none">
  <circle cx="50" cy="50" r="45" fill="#22c55e" />
</svg>

5. Making SVGs Responsive: viewBox Without width/height

The simplest way to create a responsive SVG is to set a viewBox but omit fixed width and height attributes. The SVG will then scale to fill its container while maintaining aspect ratio.

<!-- Responsive SVG: viewBox only, no width/height -->
<svg viewBox="0 0 800 400" xmlns="http://www.w3.org/2000/svg">
  <rect width="800" height="400" fill="#f0f9ff" rx="8" />
  <text x="400" y="200" text-anchor="middle" font-size="48"
        fill="#1e40af">Responsive SVG</text>
</svg>

<!-- CSS controls the rendered size -->
<style>
  svg {
    width: 100%;    /* Fill container width */
    height: auto;   /* Maintain aspect ratio */
  }
</style>

To control the rendered size, use CSS on the SVG element or its wrapper. This gives you full responsive control.

Key principle: An SVG with only a viewBox and no width/height behaves like an image with an intrinsic aspect ratio. It expands to fill available width and calculates height automatically.

<!-- Aspect ratio container with CSS -->
<div style="max-width: 600px; margin: 0 auto;">
  <svg viewBox="0 0 16 9" style="width: 100%; height: auto;">
    <!-- 16:9 aspect ratio SVG -->
    <rect width="16" height="9" fill="#e2e8f0" rx="0.5" />
  </svg>
</div>

<!-- Modern approach: CSS aspect-ratio -->
<svg viewBox="0 0 100 100" style="width: 100%; aspect-ratio: 1 / 1;">
  <circle cx="50" cy="50" r="45" fill="#8b5cf6" />
</svg>

If you need a specific aspect ratio container, use the CSS aspect-ratio property or the padding-bottom trick on a wrapper element.

6. Common Patterns: Icon Sizing, Full-Width Banners, Aspect Ratio Boxes

Icon sizing: For icons, set explicit width and height (e.g., 24x24) and a matching viewBox. This ensures crisp rendering at the intended size.

<!-- Icon: explicit size + matching viewBox -->
<svg width="24" height="24" viewBox="0 0 24 24"
     fill="none" stroke="currentColor" stroke-width="2">
  <path d="M12 2L2 7l10 5 10-5-10-5z" />
  <path d="M2 17l10 5 10-5" />
  <path d="M2 12l10 5 10-5" />
</svg>

<!-- 32px variant: same viewBox, larger width/height -->
<svg width="32" height="32" viewBox="0 0 24 24"
     fill="none" stroke="currentColor" stroke-width="2">
  <path d="M12 2L2 7l10 5 10-5-10-5z" />
</svg>

Full-width banners: Use viewBox without width/height, and set width: 100% in CSS. The SVG stretches to fill the container width, and height adjusts automatically based on the viewBox aspect ratio.

<!-- Full-width banner SVG -->
<svg viewBox="0 0 1440 320" style="width: 100%; height: auto; display: block;">
  <path fill="#3b82f6"
    d="M0,160L48,176C96,192,192,224,288,213.3C384,203,480,149,576,
       144C672,139,768,181,864,197.3C960,213,1056,203,1152,176
       C1248,149,1344,107,1392,85.3L1440,64L1440,320L0,320Z" />
</svg>

Aspect ratio boxes: Use preserveAspectRatio="none" combined with CSS width/height to stretch an SVG to any dimensions. Useful for decorative backgrounds and dividers.

<!-- Stretched decorative background -->
<svg viewBox="0 0 100 100" preserveAspectRatio="none"
     style="width: 100%; height: 200px; display: block;">
  <defs>
    <linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
      <stop offset="0%" stop-color="#3b82f6" />
      <stop offset="100%" stop-color="#8b5cf6" />
    </linearGradient>
  </defs>
  <rect width="100" height="100" fill="url(#grad)" />
</svg>

Responsive icons: Set viewBox on the SVG, omit width/height, and use CSS to control size. The icon scales without losing quality at any size.

7. React/JSX: viewBox in Components, Dynamic Sizing

In React/JSX, the viewBox attribute works the same as in HTML. The main difference is that JSX uses camelCase for most SVG attributes, but viewBox stays as viewBox (it is already camelCase).

A well-structured React SVG icon component should forward viewBox and sizing props:

// React SVG Icon component with viewBox
interface IconProps extends React.SVGProps<SVGSVGElement> {
  size?: number;
}

function Icon({ size = 24, children, ...props }: IconProps) {
  return (
    <svg
      width={size}
      height={size}
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth={2}
      strokeLinecap="round"
      strokeLinejoin="round"
      {...props}
    >
      {children}
    </svg>
  );
}

// Usage
<Icon size={16}>
  <path d="M20 6L9 17l-5-5" />
</Icon>

<Icon size={48} className="text-blue-500">
  <path d="M20 6L9 17l-5-5" />
</Icon>

For dynamic viewBox values, you can compute them from props or state:

// Dynamic viewBox for zoom/pan
function ZoomableSvg({ zoom = 1, panX = 0, panY = 0 }) {
  const size = 100 / zoom;
  const viewBox = `${panX} ${panY} ${size} ${size}`;

  return (
    <svg
      width="400"
      height="400"
      viewBox={viewBox}
      style={{ border: '1px solid #e2e8f0' }}
    >
      <circle cx="50" cy="50" r="40" fill="#3b82f6" />
      <rect x="10" y="10" width="30" height="30" fill="#ef4444" />
    </svg>
  );
}

// zoom=1 → viewBox="0 0 100 100" (default)
// zoom=2 → viewBox="0 0 50 50"   (zoomed in 2x)
// zoom=0.5 → viewBox="0 0 200 200" (zoomed out)

Common JSX mistake: Writing viewbox (all lowercase) instead of viewBox. React and the browser require the capital B.

8. CSS Control: width, height, max-width on SVG

CSS properties applied to SVG elements interact with viewBox in specific ways:

width/height in CSS override the SVG width/height attributes. If the SVG has a viewBox, the content scales to fit the CSS-defined dimensions.

max-width: 100% prevents SVGs from overflowing their container. Essential for responsive designs. Add height: auto to maintain aspect ratio.

display: block removes the extra whitespace below inline SVGs (SVGs are inline by default, which creates a small gap below them due to line-height).

The recommended responsive SVG CSS pattern:

/* Recommended responsive SVG CSS */
svg {
  display: block;       /* Remove inline whitespace gap */
  max-width: 100%;      /* Never overflow container */
  height: auto;         /* Maintain aspect ratio */
}

/* Fixed-size icon SVG */
svg.icon {
  width: 1.5em;         /* Scale with font size */
  height: 1.5em;
  vertical-align: middle;
  fill: currentColor;   /* Inherit text color */
}

/* Full-width hero SVG */
svg.hero {
  width: 100%;
  height: auto;
  display: block;
}

/* Absolute-positioned background SVG */
svg.bg-decoration {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  pointer-events: none; /* Don't block clicks */
}

/* Override SVG attributes with CSS */
svg[width="500"] {
  /* CSS wins over the HTML attribute */
  width: 100%;
  height: auto;
}

9. Debugging: Chrome DevTools SVG Inspector

When SVGs render incorrectly, Chrome DevTools offers several inspection techniques:

Elements panel: Inspect the SVG element to see its computed width, height, and viewBox. Check for missing or incorrect attributes.

Computed styles: Look at the "Computed" tab to see final CSS dimensions. The SVG's rendered size may differ from its attributes due to CSS overrides.

Box model: The box model diagram shows the SVG's actual layout size, including padding and borders. Compare this to the viewBox dimensions.

Console testing: Use document.querySelector("svg").getBBox() to get the bounding box of all SVG content. This tells you the actual coordinate range used by your paths and shapes. Use getBoundingClientRect() to get the rendered pixel dimensions.

// DevTools Console: inspect SVG dimensions

// Get the bounding box of all SVG content
const svg = document.querySelector('svg');
const bbox = svg.getBBox();
console.log('Content bounds:', bbox);
// { x: 10, y: 10, width: 180, height: 180 }

// Get the rendered pixel size
const rect = svg.getBoundingClientRect();
console.log('Rendered size:', rect.width, 'x', rect.height);

// Get the viewBox values
const viewBox = svg.viewBox.baseVal;
console.log('viewBox:', viewBox.x, viewBox.y, viewBox.width, viewBox.height);

// Tight-fit the viewBox to content
const tight = `${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}`;
svg.setAttribute('viewBox', tight);
console.log('Tight viewBox:', tight);

Outline trick: Add outline: 1px solid red to the SVG element to see its exact rendered boundaries. This helps identify viewBox/sizing mismatches.

10. Common Mistakes: Missing viewBox, Wrong Aspect Ratio, Blurry SVGs

Missing viewBox: Without a viewBox, an SVG with width="100" height="100" is fixed at 100x100 pixels. It cannot scale. Always include viewBox for scalability.

<!-- BAD: No viewBox, fixed size, cannot scale -->
<svg width="100" height="100">
  <circle cx="50" cy="50" r="40" fill="#ef4444" />
</svg>

<!-- GOOD: viewBox enables scaling -->
<svg viewBox="0 0 100 100" width="100" height="100">
  <circle cx="50" cy="50" r="40" fill="#22c55e" />
</svg>

Wrong aspect ratio: If your viewBox is 0 0 100 50 (2:1) but the SVG element is 200x200 (1:1), the content will be letterboxed or cropped depending on preserveAspectRatio. Match aspect ratios or use preserveAspectRatio intentionally.

<!-- Aspect ratio mismatch: viewBox is 2:1, element is 1:1 -->
<svg width="200" height="200" viewBox="0 0 100 50">
  <!-- Content is letterboxed by default (meet) -->
  <rect width="100" height="50" fill="#3b82f6" />
</svg>

<!-- Fix: match the aspect ratio -->
<svg width="200" height="100" viewBox="0 0 100 50">
  <rect width="100" height="50" fill="#3b82f6" />
</svg>

Blurry SVGs: SVGs should never be blurry since they are vector-based. If your SVG looks blurry, check for: (1) SVG being rasterized via <img> at a very small size, (2) CSS image-rendering set incorrectly, (3) Sub-pixel positioning — paths at fractional coordinates look fuzzy. Snap paths to whole pixels in your viewBox.

<!-- Blurry SVG fix: align paths to pixel grid -->
<!-- BAD: sub-pixel coordinates cause fuzzy edges -->
<svg viewBox="0 0 24 24">
  <rect x="3.5" y="3.5" width="17" height="17"
        stroke="#333" stroke-width="1" fill="none" />
</svg>

<!-- GOOD: whole-pixel coordinates for crisp 1px lines -->
<svg viewBox="0 0 24 24">
  <rect x="4" y="4" width="16" height="16"
        stroke="#333" stroke-width="1" fill="none" />
</svg>

viewBox="0 0 0 0": A zero-dimension viewBox makes the SVG invisible. Always use positive width and height values.

Redundant xmlns: When using inline SVG in HTML5, the xmlns attribute is optional. It is only required when the SVG is in a standalone .svg file.

Using px units in viewBox: viewBox values are unitless coordinate numbers, not pixels. Writing viewBox="0 0 100px 100px" is invalid.

Frequently Asked Questions

What happens if I set viewBox but no width or height?

The SVG becomes responsive and expands to fill its container width while maintaining the aspect ratio defined by the viewBox. This is the recommended approach for responsive SVGs. You can then control the size with CSS.

Can I animate the viewBox attribute?

Yes, you can animate viewBox using JavaScript (e.g., requestAnimationFrame) or SMIL animations. This creates smooth zoom and pan effects. In React, you can drive viewBox changes through state. CSS cannot animate viewBox directly, but JavaScript-driven transitions work well.

What is the difference between viewBox and viewport?

The viewport is the visible area of the SVG element on the page, defined by its width and height (from attributes or CSS). The viewBox defines the coordinate system mapped onto that viewport. Think of the viewport as the TV screen size and viewBox as the camera's field of view.

Why does my SVG have extra whitespace around it?

This usually happens because (1) the viewBox is larger than the actual content — use getBBox() in DevTools to find the tight bounding box, or (2) the SVG is an inline element, which adds line-height space below it — fix with display: block, or (3) preserveAspectRatio is adding letterbox space — check aspect ratio matching.

How do I make an SVG fill its container and ignore aspect ratio?

Set preserveAspectRatio="none" on the SVG element. This stretches the viewBox content to fill the viewport exactly, without maintaining aspect ratio. Set width and height to 100% via CSS. This is useful for decorative backgrounds and shape dividers.

𝕏 Twitterin LinkedIn
Var dette nyttig?

Hold deg oppdatert

Få ukentlige dev-tips og nye verktøy.

Ingen spam. Avslutt når som helst.

Try These Related Tools

SVGSVG to JSX/React💎SVG Optimizer🖼️Image Base64 Converter

Related Articles

SVG i React: Fra rå SVG til optimaliserte komponenter

Lær å transformere rå SVG til effektive React-komponenter. SVGO-optimalisering, tilgjengelighet, animasjoner og TypeScript-props.

HTML til JSX: Alt du trenger for React-migrering

Komplett guide for konvertering av HTML til JSX for React. className, style-objekter, selvlukkende tagger, event-handlere og vanlige feller.