Search code examples
svgaspect-ratiolighthouse

Google Lighthouse and SVGs with preserveAspectRatio="none"


Google Lighthouse has a red triangle error which significantly impacts the Best Practices score:

  • Displays images with incorrect aspect ratio

I can understand why this would be regarded as an error with fixed-dimension raster images (and also with standard SVG vector images with explicitly set dimensions).

But in this case I'm displaying a small number of SVG flags on a webpage and the SVG flags display with certain dimensions in one part of the page and different dimensions in another part.

To enable using the same single SVG even when multiple instances of that SVG display with different dimensions, I use the attribute:

preserveAspectRatio="none"

This explicitly means (I would hope) that there is no incorrect aspect ratio.

But Google Lighthouse raises the error above, nevertheless.

At normal desktop browser size the graphics are quite small (either 27px x 27px or 27px x 18px) so, yes, I could potentially replace them with .png or .webp images.

But then I'd also need to bear in mind that the flag-image dimensions also increase in size very slightly at narrower responsive design breakpoints, so I would need a full set of fixed-dimension raster images for each breakpoint.

Is there any way I can instruct Google Lighthouse to ignore aspect ratio for SVG images which explicitly state preserveAspectRatio="none"?


Solution

  • Lighthouse reports the error:

    • Displays images with incorrect aspect ratio

    precisely because the SVG includes the preserveAspectRatio="none" attribute.

    In two specific contexts:

    • the SVG has no viewBox attribute
    • the SVG includes the preserveAspectRatio="none" attribute

    the intrinsic dimensions of the SVG default to standard replaced element dimensions:

    • 300px x 150px.

    This gives the SVG an intrinsic aspect ratio of 1:2.

    At this point, if the SVG is displayed on a webpage with a different aspect ratio, Lighthouse will report the error above.


    Including the viewBox attribute

    Otherwise, the viewBox attribute will determine the intrinsic dimensions and intrinsic aspect ratio of the SVG.

    Like any other <img>, the SVG may be styled via CSS to have any width and any height. But the aspect ratio resulting from these values must be identical to the intrinsic aspect ratio determined by the SVG's viewBox.

    Hence, an SVG can have a CSS width and height which scale it infinitely upwards or infinitely downwards - but they cannot alter the shape of the SVG as defined by the viewBox.

    If the CSS values change the shape of the SVG, Lighthouse will will report the error above.


    Conclusions

    To avoid the Lighthouse error above:

    1. The SVG must have a viewBox attribute
    2. The SVG may not use preserveAspectRation="none"
    3. the CSS width vs height aspect ratio and the SVG viewBox aspect ratio must match

    Also note:

    Declaring the CSS property aspect-ratio or HTML width and height attributes will not help in this situation. Neither CSS nor HTML are capable of overriding the intrinsic dimensions established by the SVG viewBox.


    Example:

    If you have an SVG with

    viewBox="0 0 360 360"
    

    then, using CSS, you can display that SVG as an at any size as long as it maintains an aspect ratio of 1:1.

    E.g.

    • width: 24px; height: 24px;
    • width: 36px; height: 36px;
    • width: 48px; height: 48px; etc.

    But, should you wish to style the same SVG-based <img> with a different aspect ratio:

    • width: 36px; height: 24px; // aspect ratio of 3:2

    then you must create a new SVG with a viewBox which establishes an aspect ratio consistent with the CSS values:

    viewBox="0 0 540 360"
    

    if you don't want Lighthouse to report an incorrect aspect ratio error.