Scaling of SVG backgrounds

  • Revision slug: CSS/Scaling_of_SVG_backgrounds
  • Revision title: Scaling of SVG backgrounds
  • Revision id: 66843
  • Created:
  • Creator: Sheppy
  • Is current revision? No
  • Comment 401 words added

Revision Content

Given the flexibility of SVG images, there's a lot to keep in mind when using them as background images with the {{ cssxref("background-image") }} property, and even more to keep in mind when also scaling them using the {{ cssxref("background-size") }} property. This article describes how scaling of SVG images is handled when using these properties.

The algorithm, in summary

The algorithm can for the most part be summarized by these four rules. There are some edge cases that aren't covered by these rules, but this covers the majority of cases.

  1. If {{ cssxref("background-size") }} specifies a fixed dimension (that is, percentages and relative units are fixed by their context), that dimension wins.
  2. If the image has an intrinsic ratio (that is, its width:height ratio is constant, such as 16:9, 4:3, 2.39:1, 1:1, and so forth), the rendered size preserves that ratio.
  3. If the image specifies a size, and the size isn't modified by constrain or cover, that specified size wins.
  4. If none of the above cases are met, the image is rendered at the same size as the background area.

It's worth noting that the sizing algorithm only cares about the image's dimensions and proportions, or lack thereof. An SVG image with fixed dimensions will be treated just like a raster image of the same size.

Source image examples

Before diving in to look at the results of using different kinds of source images and seeing how they look when used with {{ cssxref("background-size") }}, it would be helpful to look at a few example source images that have different dimensions and sizing settings.

In each case, we show what the source image looks like rendered in a 150x150 box, and provide a link to the SVG source.

Dimensionless and proportionless

This image is both dimensionless and proportionless. It doesn't care what size it is, nor does it care about remaining at a particular aspect ratio. This would make a good gradient desktop background that would work regardless of your screen size and its aspect ratio.

no-dimensions-or-ratio.png

SVG source

One specified dimension and proportionless

This image specifies a width of 100 pixels but no height or intrinsic ratio. This is, basically, a thin strip of wallpaper that could be stretched across the entire height of a block.

100px-wide-no-height-or-ratio.png

SVG source

One specified dimension with intrinsic ratio

This image specifies a 100 pixel height but no width. It also specifies an intrinsic aspect ratio of 3:4. This ensures that its width:height ratio is always 3:4, unless it's deliberately scaled to a disproportionate size (that is, by explicitly specifying both width and height that aren't of that ratio).

This is very much like specifying a specific width and height, since once you have one dimension and a ratio, the other dimension is implied, but it's still a useful example.

100px-height-3x4-ratio.png

SVG source

No width or height with intrinsic ratio

This image doesn't specify either a width or a height; instead, it specifies an intrinsic ratio of 1:1. Think of this like a program icon. It's always square, and is usable at any size, such as 32x32, 128x128, or 512x512, for example.

no-dimensions-1x1-ratio.png

SVG source

Scaling examples

Now let's see some examples of what happens as we apply different scaling to these images. In each of the examples below, the enclosing rectangles are 300 pixels wide and 300 pixels tall. In addition, the backgrounds have {{ cssxref("background-repeat") }} set to no-repeat for clarity.

Note: The screenshots below show the expected rendering. Not all browsers currently render these correctly.

Specifying fixed lengths for both dimensions

If you use {{ cssxref("background-size") }} to specify fixed lengths for both dimensions, those lengths are always used, per rule 1 above. In other words, the image will always get stretched to the dimensions you specify, regardless of whether or not the source image has specified its dimensions and/or aspect ratio.

Source: No dimensions or intrinsic ratio

Given this CSS:

background: url(no-dimensions-or-ratio.svg);
background-size: 125px 175px;

The rendered output would look like this:

fixed-no-dimensions-or-ratio.png

Source: One specified dimension, no intrinsic ratio

Given this CSS:

background: url(100px-wide-no-height-or-ratio.svg);
background-size: 250px 150px;

The rendered output would look like this:

fixed-100px-wide-no-height-or-ratio.png

Source: One specified dimension with intrinsic ratio

Given this CSS:

background: url(100px-height-3x4-ratio.svg);
background-size: 275px 125px;

The rendered output would look like this:

fixed-100px-height-3x4-ratio.png

Source: No specified width or height with intrinsic ratio

Given this CSS:

background: url(no-dimensions-1x1-ratio.svg);
background-size: 250px 100px;

The rendered output would look like this:

fixed-no-dimensions-1x1-ratio.png

Using contain or cover

Specifying cover for {{ cssxref("background-size") }} makes the picture as small as possible while still covering the entire background area. contain, on the other hand, makes the image as large as possible while not being clipped by the background area.

For an image with an intrinsic ratio, exactly one size matches the cover/fit criteria alone. But if there is no intrinsic ratio specified, cover/fit isn't sufficient, so the large/small constraints choose the resulting size.

In this case, rule 1 isn't relevant, so rule 2 is applied: we try to preserve any intrinsic ratio (while respecting contain or cover). For example, preserving a 3:4 intrinsic aspect ratio for a 300x200 box with contain means drawing a 150x200 background.

Source: No dimensions or intrinsic ratio

If an image doesn't specify either dimensions or an intrinsic ratio, neither rule 2 nor rule 3 apply, so rule 4 takes over: the background image is rendered covering the entire background area. This satisfies the largest-or-smallest constraint.

background: url(no-dimensions-or-ratio.svg);
background-size: contain;

The rendered output looks like this:

 

Revision Source

<p>Given the flexibility of SVG images, there's a lot to keep in mind when using them as background images with the {{ cssxref("background-image") }} property, and even more to keep in mind when also scaling them using the {{ cssxref("background-size") }} property. This article describes how scaling of SVG images is handled when using these properties.</p>
<h2>The algorithm, in summary</h2>
<p>The algorithm can for the most part be summarized by these four rules. There are some edge cases that aren't covered by these rules, but this covers the majority of cases.</p>
<ol> <li>If {{ cssxref("background-size") }} specifies a fixed dimension (that is, percentages and relative units are fixed by their context), that dimension wins.</li> <li>If the image has an intrinsic ratio (that is, its width:height ratio is constant, such as 16:9, 4:3, 2.39:1, 1:1, and so forth), the rendered size preserves that ratio.</li> <li>If the image specifies a size, and the size isn't modified by constrain or cover, that specified size wins.</li> <li>If none of the above cases are met, the image is rendered at the same size as the background area.</li>
</ol>
<p>It's worth noting that the sizing algorithm only cares about the image's dimensions and proportions, or lack thereof. An SVG image with fixed dimensions will be treated just like a raster image of the same size.</p>
<h2>Source image examples</h2>
<p>Before diving in to look at the results of using different kinds of source images and seeing how they look when used with {{ cssxref("background-size") }}, it would be helpful to look at a few example source images that have different dimensions and sizing settings.</p>
<p>In each case, we show what the source image looks like rendered in a 150x150 box, and provide a link to the SVG source.</p>
<h3>Dimensionless and proportionless</h3>
<p>This image is both dimensionless and proportionless. It doesn't care what size it is, nor does it care about remaining at a particular aspect ratio. This would make a good gradient desktop background that would work regardless of your screen size and its aspect ratio.</p>
<p><img alt="no-dimensions-or-ratio.png" class="internal default" src="/@api/deki/files/5860/=no-dimensions-or-ratio.png" style=""></p>
<p><a href="/@api/deki/files/5864/=no-dimensions-or-ratio.svg" title="no-dimensions-or-ratio.svg">SVG source</a></p>
<h3>One specified dimension and proportionless</h3>
<p>This image specifies a width of 100 pixels but no height or intrinsic ratio. This is, basically, a thin strip of wallpaper that could be stretched across the entire height of a block.</p>
<p><img alt="100px-wide-no-height-or-ratio.png" class="internal default" src="/@api/deki/files/5858/=100px-wide-no-height-or-ratio.png"></p>
<p><a href="/@api/deki/files/5863/=100px-wide-no-height-or-ratio.svg" title="100px-wide-no-height-or-ratio.svg">SVG source</a></p>
<h3>One specified dimension with intrinsic ratio</h3>
<p>This image specifies a 100 pixel height but no width. It also specifies an intrinsic aspect ratio of 3:4. This ensures that its width:height ratio is always 3:4, unless it's deliberately scaled to a disproportionate size (that is, by explicitly specifying both width and height that aren't of that ratio).</p>
<p>This is very much like specifying a specific width and height, since once you have one dimension and a ratio, the other dimension is implied, but it's still a useful example.</p>
<p><img alt="100px-height-3x4-ratio.png" class="internal default" src="/@api/deki/files/5857/=100px-height-3x4-ratio.png"></p>
<p><a href="/@api/deki/files/5862/=100px-height-3x4-ratio.svg" title="100px-height-3x4-ratio.svg">SVG source</a></p>
<h3>No width or height with intrinsic ratio</h3>
<p>This image doesn't specify either a width or a height; instead, it specifies an intrinsic ratio of 1:1. Think of this like a program icon. It's always square, and is usable at any size, such as 32x32, 128x128, or 512x512, for example.</p>
<p><img alt="no-dimensions-1x1-ratio.png" class="internal default" src="/@api/deki/files/5859/=no-dimensions-1x1-ratio.png"></p>
<p><a href="/@api/deki/files/5861/=no-dimensions-1x1-ratio.svg" title="no-dimensions-1x1-ratio.svg">SVG source</a></p>
<h2>Scaling examples</h2>
<p>Now let's see some examples of what happens as we apply different scaling to these images. In each of the examples below, the enclosing rectangles are 300 pixels wide and 300 pixels tall. In addition, the backgrounds have {{ cssxref("background-repeat") }} set to no-repeat for clarity.</p>
<div class="note"><strong>Note:</strong> The screenshots below show the <strong>expected</strong> rendering. Not all browsers currently render these correctly.</div>
<h3>Specifying fixed lengths for both dimensions</h3>
<p>If you use {{ cssxref("background-size") }} to specify fixed lengths for both dimensions, those lengths are always used, per rule 1 above. In other words, the image will always get stretched to the dimensions you specify, regardless of whether or not the source image has specified its dimensions and/or aspect ratio.</p>
<h4>Source: No dimensions or intrinsic ratio</h4>
<p>Given this CSS:</p>
<pre>background: url(no-dimensions-or-ratio.svg);
background-size: 125px 175px;
</pre>
<p>The rendered output would look like this:</p>
<p><img alt="fixed-no-dimensions-or-ratio.png" class="internal default" src="/@api/deki/files/5868/=fixed-no-dimensions-or-ratio.png" style=""></p>
<h4>Source: One specified dimension, no intrinsic ratio</h4>
<p>Given this CSS:</p>
<pre>background: url(100px-wide-no-height-or-ratio.svg);
background-size: 250px 150px;
</pre>
<p>The rendered output would look like this:</p>
<p><img alt="fixed-100px-wide-no-height-or-ratio.png" class="internal default" src="/@api/deki/files/5866/=fixed-100px-wide-no-height-or-ratio.png"></p>
<h4>Source: One specified dimension with intrinsic ratio</h4>
<p>Given this CSS:</p>
<pre>background: url(100px-height-3x4-ratio.svg);
background-size: 275px 125px;
</pre>
<p>The rendered output would look like this:</p>
<p><img alt="fixed-100px-height-3x4-ratio.png" class="internal default" src="/@api/deki/files/5865/=fixed-100px-height-3x4-ratio.png"></p>
<h4>Source: No specified width or height with intrinsic ratio</h4>
<p>Given this CSS:</p>
<pre class="note">background: url(no-dimensions-1x1-ratio.svg);
background-size: 250px 100px;
</pre>
<p>The rendered output would look like this:</p>
<p><img alt="fixed-no-dimensions-1x1-ratio.png" class="internal default" src="/@api/deki/files/5867/=fixed-no-dimensions-1x1-ratio.png" style=""></p>
<h3>Using contain or cover</h3>
<p>Specifying <code>cover</code> for {{ cssxref("background-size") }} makes the picture as small as possible while still covering the entire background area. <code>contain</code>, on the other hand, makes the image as large as possible while not being clipped by the background area.</p>
<p>For an image with an intrinsic ratio, exactly one size matches the <code>cover</code>/fit criteria alone. But if there is no intrinsic ratio specified, <code>cover</code>/fit isn't sufficient, so the large/small constraints choose the resulting size.</p>
<p>In this case, rule 1 isn't relevant, so rule 2 is applied: we try to preserve any intrinsic ratio (while respecting <code>contain</code> or <code>cover</code>). For example, preserving a 3:4 intrinsic aspect ratio for a 300x200 box with <code>contain</code> means drawing a 150x200 background.</p>
<h4>Source: No dimensions or intrinsic ratio</h4>
<p>If an image doesn't specify either dimensions or an intrinsic ratio, neither rule 2 nor rule 3 apply, so rule 4 takes over: the background image is rendered covering the entire background area. This satisfies the largest-or-smallest constraint.</p>
<pre>background: url(no-dimensions-or-ratio.svg);
background-size: contain;
</pre>
<p>The rendered output looks like this:</p>
<p> </p>
Revert to this revision