Cropping & Scaling Images Using SVG Documents
Articles & Blogs

Cropping & Scaling Images Using SVG Documents

Jan 1, 2018

<p class="deck"> I’m always interested in and thinking about ways to use SVG in my client projects to solve common UI challenges — uses that go beyond simple icon display and animated illustrations. I’m also always researching and looking for practical uses of SVG to add to my <a href="https://www.sarasoueidan.com/speaking/">talk</a> and workshops material that go beyond SVG the image format, and more into the document nature of it. After all, SVG on the Web isn’t just about displaying pretty and animated illustrations. </p> <p> I’m also particularly interested in CSS and SVG as a combination (that I like to call “The Power Combo”) to solve common real-world challenges. These two work <em>really</em> well together. And it so happens than some of what’s possible in CSS is also possible in SVG, either because the CSS functionlity was imported from SVG to begin with, or simply because SVG documents also happen to offer tools that achieve the same functionality. And since SVG goes way back and has much better support than newer CSS features, it is possible to use SVG either as a fallback or as a replacement to some CSS functionalities. It all depends on the browser support you’re after. </p> <p>SVG comes with a pair of attributes — namely <code>viewBox</code> and <code>preserveAspectRatio</code> — that allow us to manipulate the contents of an SVG (whether vector content or raster images) in a myriad of ways to achieve a myriad of things. One thing we can do with these attributes is control the scaling and position of the contents of the SVG. In this article, we’ll use these attributes to crop, scale and position images, as a fallback or alternative to the CSS <code>object-fit</code> and <code>object-position</code> properties.</p> <div class="note"> If you’re not familiar with the SVG <code>viewBox</code>, viewport and <code>preserveAspectRatio</code>, I highly recommend reading <a href="https://www.sarasoueidan.com/blog/svg-coordinate-systems">my extensive guide</a> on the subject. Although this article does not require a deep understanding of these attributes, I highly recommend you get comfortable using these attributes. </div> <h3 id="cropping%2C-scaling-and-positioning-in-css-with-object-fit-and-object-position" tabindex="-1">Cropping, Scaling and Positioning in CSS with <code>object-fit</code> and <code>object-position</code></h3> <p>Say you’re using a CMS, and you’re allowing your users or authors to upload photos of themselves to use as an avatar next to their biography on the site. And you want to make it possible for them to upload any image of any size and aspect ratio, and then you’d handle the cropping of that image before you display it on the page in a box that might very well have a different aspect ratio than the image the author uploaded.</p> <p>There are many ways you could handle this. For example, you can handle the image cropping on the server-side using PHP or some JavaScript script, and then serve the cropped image on the site. You may even be in a different scenario, where you just want to be able to quickly crop and display the images on a page, without using a CMS and back-end script.</p> <p>Fortunately, today, CSS has two properties that make cropping and scaling images within a fitted box a breeze. These properties are <code>object-fit</code> and <code>object-position</code>.</p> <p>The <code>object-fit</code> property specifies how the contents of a <a aria-describedby="footnote-label" href="https://www.sarasoueidan.com/blog/svg-object-fit/#replaced-element" id="replaced-element-ref">replaced element</a> should be fitted to the box established by its used height and width.</p> <p>Even though a bitmap image has its own intrinsic dimensions and aspect ratio, you can size it to fit into any box of any size as defined in your CSS. And you can choose whether you want to preserve the aspect ratio of the image or not, all using one property (<code>object-fit</code>) and one line of CSS.</p> <p>The following image shows the effect of each of the possible values for <code>object-fit</code>:</p> <figure> <img src="https://www.sarasoueidan.com/assets/images/object-fit-values.png" alt="object-fit values" /> <figcaption> The result of applying the different <code>object-fit</code> values to an image to be fitted in a box with a different aspect ratio. </figcaption> </figure> <p>By default, the image is centered within its containing box (the square, in our example). You can change that default position using <code>object-position</code>, which takes values similar to the values of <code>background-position</code>. For example, <code>object-position: top left</code> will align the top edge of the image to the top border of the box, and the left edge of the image to the left border of the box. Here’s a live Codepen for you to try the effect of changing <code>object-position</code> on the images:</p> <p data-height="1000" data-theme-id="3617" data-slug-hash="31c6225244914f3967b3f7c773394c6c" data-default-tab="result" data-user="SaraSoueidan" data-embed-version="2" data-pen-title="CSS object-fit Values" class="codepen">See the Pen <a href="https://codepen.io/SaraSoueidan/pen/31c6225244914f3967b3f7c773394c6c/">CSS object-fit Values</a> by Sara Soueidan (<a href="https://codepen.io/SaraSoueidan">@SaraSoueidan</a>) on <a href="https://codepen.io/">CodePen</a>.</p> <script async="" src="https://production-assets.codepen.io/assets/embed/ei.js"></script> <p>Browser support for <code>object-fit</code> and <code>object-position</code> is very good: it is supported in all the latest browsers, including MS Edge 16+ and Opera Mini, though it requires the <code>-o-</code> prefix in the latter. You can see the latest updated browser support <a href="https://caniuse.com/#feat=object-fit">on CanIUse.com</a>.</p> <p>If you, like me, want to be able to provide a similar experience to Internet Explorer, you’re going to need an alternative solution, or at least a fallback. And, ideally, the alternative solution needs to provide support at least back to IE9, maybe? This is where SVG can fill in.</p> <h3 id="cropping-%26-scaling-images-with-svg" tabindex="-1">Cropping &amp; Scaling Images with SVG</h3> <p>If you’ve ever played with the SVG <code>viewBox</code>, then you know that the coordinate system defined by the <code>viewBox</code> does not necessarily need to have the same aspect ratio as <a href="https://www.sarasoueidan.com/blog/svg-object-fit/#viewport-coordinate-system" id="viewport-coordinate-system-ref" aria-describedby="footnote-label">that of the <code>&lt;svg&gt;</code> viewport</a>.</p> <p>And when the aspect ratio of the <code>viewBox</code> is not the same as that of the viewport, the browser needs to position the former in the latter similar to the way the photo was being positioned inside the box in the previous section.</p> <p>By default, just like with <code>object-fit</code>, the browser will fit the <code>viewBox</code> inside of the SVG viewport (or “box”) by <em>containing</em> it inside of it, such that the entire <code>viewBox</code> — and, thus, all the contents of the SVG — are visible inside the viewport.</p> <p>Using the <code>preserveAspectRatio</code> attribute, you can change the position and scale of the <code>viewBox</code> — and, thus, all the contents of the SVG — similar to the way <code>object-position</code> changes the position and scale of the image inside the box when using <code>object-fit</code>.</p> <p>For example, suppose we have a square svg (aspect ratio 1:1) and a <code>viewBox</code> that has a different aspect ratio (2:1). The easiest and fastest way to visualize the <code>viewBox</code> coordinate system in the svg is to create a <code>&lt;rect&gt;</code> that <a href="https://www.sarasoueidan.com/blog/svg-object-fit/#viewbox-origin" id="viewbox-origin-ref" aria-describedby="footnote-label">starts at the coordinate system’s origin</a> and has a width and height value of <code>100%</code>.</p> <pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>300px<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>300px<span class="token punctuation">"</span></span> <span class="token attr-name">viewBox</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0 0 500 250<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"> <span class="token comment">&lt;!-- This rect is the same size of the viewBox --></span></span><br /><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>rect</span> <span class="token attr-name">x</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0<span class="token punctuation">"</span></span> <span class="token attr-name">y</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0<span class="token punctuation">"</span></span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span> <span class="token attr-name">fill</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#FEDA00<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>rect</span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">></span></span></span></code></pre> <p>The result of the above code is shown in the image below. The yellow rectangle represent the size and position of the <code>viewBox</code> within the svg viewport.</p> <figure> <img src="https://www.sarasoueidan.com/assets/images/viewbox-vs-viewport-aspect-ratio.png" alt="Screenshot of an SVG containing a viewBox and rect with different aspect ratio." /> <figcaption> The result of applying the different <code>object-fit</code> values to an image to be fitted in a box with a different aspect ratio. </figcaption> </figure> <p>Now, using <code>preserveAspectRatio</code>, you can change the position of the viewBox as well as its size (or scale) within the viewport similar to the same way we could change the position and scale of our image in the previous section using <code>object-fit</code> and <code>object-position</code>.</p> <hr /> <p>A <code>preserveAspectRatio</code> value is made up of two keywords, one of them represents the scale <code>viewBox</code> and has one of two values: <code>meet</code> or <code>slice</code>.</p> <p><code>meet</code> has the same effect as <code>object-fit: contain;</code> (or <code>background-size: contain;</code>) and <code>slice</code> has the same effect as <code>object-fit: cover;</code> (or <code>background-size: cover;</code>). The former will preserve the aspect ratio of the viewBox and fit it inside the viewport so that it’s entirely visible. This is the default behavior. Whereas <code>slice</code> will scale the viewBox up, while preserving its aspect ratio, so that it covers the entire viewport area, even if it means cutting some of the content off (hence the “slicing” effect).</p> <p>The other keyword in <code>preserveAspectRatio</code> represents and controls the position of the <code>viewBox</code> within the viewport. It has 19 values, including <code>none</code> which tells the browser to scale the <code>viewBox</code> to fill the viewport area without preserving its aspect ratio, and is similar in effect to <code>object-fit: fill;</code>.</p> <p>The default value for the <code>preserveAspectRatio</code> is <code>xMidYMid meet</code>, which is the value the browser uses even if you completely omit the attribute from the <code>&lt;svg&gt;</code>.</p> <p>The following snippet using <code>preserveAspectRatio=&quot;xMinYMin meet</code> will change the position of the <code>viewBox</code> in the previous example such that the yellow rectangle’s top edge is aligned with the viewport’s top edge, and its left edge is aligned with the left edge of the viewport, while keeping the whole rectangle contained within the viewport and preserving its aspect ratio. <code>xMinYMin</code> is equivalent to <code>0% 0%</code> or <code>left top</code> values in <code>background-position</code>.</p> <pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>300px<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>300px<span class="token punctuation">"</span></span> <span class="token attr-name">viewBox</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0 0 500 250<span class="token punctuation">"</span></span> <span class="token attr-name">preserveAspectRatio</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>xMinYMin meet<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"> <span class="token comment">&lt;!-- This rect is the same size of the viewBox --></span></span><br /><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>rect</span> <span class="token attr-name">x</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0<span class="token punctuation">"</span></span> <span class="token attr-name">y</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0<span class="token punctuation">"</span></span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span> <span class="token attr-name">fill</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#FEDA00<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>rect</span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">></span></span></span></code></pre> <div class="note"> I’ve created <a href="http://www.sarasoueidan.com/demos/interactive-svg-coordinate-system/">an interactive demo</a> that includes a cheatsheet that maps each of the <code>preserveAspectRatio</code> values to one of <code>background-position</code> values. I highly recommend checking it out. </div> <p>Now, to get back to the objective of this article. If you replace the <code>&lt;rect&gt;</code> element with an image (such as a photograph) and you match the aspect ratio of that image with that of the <code>viewBox</code>, the browser’s default behavior will be to position the <code>viewBox</code> (and consequently also the image) so that it is fully contained and centered within the viewport (assuming again that the viewport’s aspect ratio is different from that of the <code>viewBox</code> and the image).</p> <p>The following Codepen shows that in action. We have a 1:1 aspect ratio SVG, and an image with dimensions 579px by 375px. I’m using the same as the one I used in the CSS demo in the previous section again, and I’m keeping the default <code>preserveAspectRatio</code>. Try changing the value of <code>preserveAspectRatio</code> to see how the changes affect the position and scale of the image within the SVG.</p> <p>To get the effect of <code>object-fit: cover;</code>, for example, you need only change <code>meet</code> into <code>slice</code> — the image will remain centered by default with <code>xMidYMid</code>.</p> <p data-height="450" data-theme-id="3617" data-slug-hash="b47336d56a318d056218aa57e8889f3a" data-default-tab="html,result" data-user="SaraSoueidan" data-embed-version="2" data-pen-title="b47336d56a318d056218aa57e8889f3a" class="codepen">See the Pen <a href="https://codepen.io/SaraSoueidan/pen/b47336d56a318d056218aa57e8889f3a/">b47336d56a318d056218aa57e8889f3a</a> by Sara Soueidan (<a href="https://codepen.io/SaraSoueidan">@SaraSoueidan</a>) on <a href="https://codepen.io/">CodePen</a>.</p> <script async="" src="https://production-assets.codepen.io/assets/embed/ei.js"></script> <p>Pretty much any combination of values of <code>object-fit</code> and <code>object-position</code> can be replicated using <code>preserveAspectRatio</code> on <code>viewBox</code>. And what’s best is that this technique will work in any and all browsers that support SVG, which means that it will work in Internet Explorer all the way back to IE9. IE8 does not support SVG so you’d have to provide a different solution for it if you need to support it.</p> <h3 id="one-more-thing%3A-making-the-svg-solution-more-accessible." tabindex="-1">One more thing: making the SVG solution more accessible.</h3> <p>One thing that the SVG solution is missing at this point is an alternative to the <code>alt</code> attribute, because an image should <em>always</em> have that. If the image is just decoration, the <code>alt</code> attribute can be left empty, but it should never be omitted.</p> <p>To make the SVG snippet accessible, you can add the SVG alternative to <code>alt</code>: the <code>&lt;title&gt;</code> element, first thing in the SVG, before your <code>&lt;image&gt;</code> declaration. So, doing that in the example above, the code would look like this:</p> <pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>300px<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>300px<span class="token punctuation">"</span></span> <span class="token attr-name">viewBox</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0 0 579 375<span class="token punctuation">"</span></span> <span class="token attr-name">preserveAspectRatio</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>xMidYMid meet<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"></span><br /><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>title<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Painter’s Hands<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"> </span><br /><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>image</span> <span class="token attr-name"><span class="token namespace">xlink:</span>href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://s3-us-west-2.amazonaws.com/s.cdpn.io/9674/photo-1501366062246-723b4d3e4eb6.jpg<span class="token punctuation">"</span></span> <span class="token attr-name">x</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0<span class="token punctuation">"</span></span> <span class="token attr-name">y</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0<span class="token punctuation">"</span></span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>image</span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"> </span><br /><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">></span></span></span></code></pre> <p>Last but not least, to <a href="https://developer.paciellogroup.com/blog/2013/12/using-aria-enhance-svg-accessibility/">enhance the accessibility of SVG</a> further, add a couple of attributes on the <code>&lt;svg&gt;</code> element to describe the role of the <code>&lt;svg&gt;</code> as well as re-enforce the relationship between the <code>&lt;svg&gt;</code> and the <code>&lt;title&gt;</code> element, so that the latter is recognised by screen readers as the accessible name for the SVG content (—our image, in this case).</p> <pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>300px<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>300px<span class="token punctuation">"</span></span> <span class="token attr-name">viewBox</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0 0 579 375<span class="token punctuation">"</span></span> <br /><span class="highlight-line"> <span class="token attr-name">preserveAspectRatio</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>xMidYMid meet<span class="token punctuation">"</span></span></span><br /> <span class="token attr-name">aria-labelledby</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>title<span class="token punctuation">"</span></span> <span class="token attr-name">aria-role</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>img<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><br /><span class="highlight-line"></span><br /><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>title<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Painter’s Hands<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"> </span><br /><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>image</span> <span class="token attr-name"><span class="token namespace">xlink:</span>href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://s3-us-west-2.amazonaws.com/s.cdpn.io/9674/photo-1501366062246-723b4d3e4eb6.jpg<span class="token punctuation">"</span></span> <span class="token attr-name">x</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0<span class="token punctuation">"</span></span> <span class="token attr-name">y</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0<span class="token punctuation">"</span></span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>image</span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"> </span><br /><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">></span></span></span></code></pre> <p>And just like that, you now have a perfectly accessible SVG alternative to a CSS <code>object-fit</code> declaration.</p> <h3 id="summary-%26-recap" tabindex="-1">Summary &amp; Recap</h3> <p>You can crop and scale any image using CSS <code>object-fit</code> and <code>object-position</code>. However, these properties are only supported in the latest version of ME Edge as well as all other modern browsers.</p> <p>If you need to crop and scale an image in Internet Explorer and provide support back to IE9, you can do that by wrapping the image in an <code>&lt;svg&gt;</code>, and using the <code>viewBox</code> and <code>preserveAspectRatio</code> attributes to do what <code>object-fit</code> and <code>object-position</code> do.</p> <p>The snippet can replace an <code>object-fit</code> declaration:</p> <pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>x<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>y<span class="token punctuation">"</span></span> <br /><span class="highlight-line"> <span class="token attr-name">viewBox</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0 0 imgX imgY<span class="token punctuation">"</span></span> </span><br /> <span class="token attr-name">preserveAspectRatio</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>&lt;align> &lt;meetOrSlice>”<br /> aria-labelledby=<span class="token punctuation">"</span></span><span class="token attr-name">title"</span> <span class="token attr-name">aria-role</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>img<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><br /><span class="highlight-line"></span><br /><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>title<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> img alt here <span class="token entity named-entity" title="&ly;">&amp;ly;</span>/title></span><br /><span class="highlight-line"></span><br /><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>image</span> <span class="token attr-name"><span class="token namespace">xlink:</span>href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>...<span class="token punctuation">"</span></span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>100%<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span>“100%”</span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>image</span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"></span><br /><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">></span></span></span></code></pre> <p>where <code>imgX</code> and <code>imgY</code> are the dimensions of the image you want to crop and scale, and <code>&lt;align&gt;</code> and <code>&lt;meetOrslice&gt;</code> are the two keywords that determine the scale and position of the image within the SVG wrapper.</p> <p>And that’s it. A simple SVG tip to provide better cross-browser support for a less-supported CSS feature.</p> <p>I hope you like this tip and find it useful. Thank you for reading!</p> <div class="footnotes"> <h4 id="footnotes_title">Footnotes</h4> <ol class="footnoteslist"> <li class="footnotesitem" id="replaced-element"> <p> A replaced element is an element whose dimensions and content are defined outside the scope of CSS. For example, a bitmap image has an intrinsic width and an intrinsic height specified in absolute units, and from which the intrinsic ratio can be determined. Dudley Storey puts it nicely when he says that ‘another way of thinking of replaced elements is “any tag that has its content replaced by an outside source”. <code>&lt;img&gt;</code> and <code>&lt;video&gt;</code> are obvious examples’. <a href="https://www.sarasoueidan.com/blog/svg-object-fit/#replaced-element-ref" aria-label="Back to content">↵</a> </p> </li> <li class="footnotesitem" id="viewport-coordinate-system"> <p> <a href="https://www.sarasoueidan.com/blog/svg-object-fit/#viewport-coordinate-system-ref" aria-label="Back to content">↵</a> </p> </li> <li class="footnotes_item" id="viewbox-origin"> <p> If the origin of the <code>viewBox</code> is changed, the origin of the <code>rect</code> should be changed to match that, otherwise the rectangle can no longer be used as a visualization of the current user coordinate system in use. <a href="https://www.sarasoueidan.com/blog/svg-object-fit/#viewbox-origin-ref" aria-label="Back to content">↵</a> </p> </li> </ol> </div>

Jump to
Projectsbrowse
Peoplebrowse
Companiesbrowse
Saved
Editor
Autosaves as you type