Skip to content

Instantly share code, notes, and snippets.

@myyellowshoe
Last active February 15, 2023 08:04
Show Gist options
  • Save myyellowshoe/e05dafdcc0f35a4d631db4c02a410eaa to your computer and use it in GitHub Desktop.
Save myyellowshoe/e05dafdcc0f35a4d631db4c02a410eaa to your computer and use it in GitHub Desktop.
Auto Scaling Svg Solution

Autoscaling SVG's

Scaling svgs is annoying and most solutions require tradoffs I don't want. I'm suprised the ammount of solutions out there that are pretty subpar or require extra overhead.

What I don't want:

  • use an image tag
  • use wrappers
  • use weird padding
  • pass down props for width/height or viewBox props.

What I want:

  • Preserve Aspect Ratio
  • Be able to modify my svg via css
  • Provide width/height and have svg scale automatically.

Solution

preserveAspectRatio="xMidYMid meet"

Simply replace width/height with this property on an svg, and voila.

<svg width="12" height="7" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.00019 6.5C5.73438 6.50154 5.4789 6.39719 5.29019 6.21L1.29019 2.21C0.898063 1.81788 0.898063 1.18212 1.29019 0.790002C1.68231 0.39788 2.31807 0.39788 2.71019 0.790002L6.00019 4.1L9.30019 0.920002V0.920002C9.66949 0.509354 10.3018 0.475839 10.7124 0.845145C11.1231 1.21445 11.1566 1.84672 10.7873 2.25737C10.7542 2.29419 10.7184 2.32849 10.6802 2.36L6.68018 6.22C6.49731 6.39632 6.25419 6.49643 6.00018 6.5L6.00019 6.5Z" fill="#3B3EC9"/>
</svg>

Becomes

<svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.00019 6.5C5.73438 6.50154 5.4789 6.39719 5.29019 6.21L1.29019 2.21C0.898063 1.81788 0.898063 1.18212 1.29019 0.790002C1.68231 0.39788 2.31807 0.39788 2.71019 0.790002L6.00019 4.1L9.30019 0.920002V0.920002C9.66949 0.509354 10.3018 0.475839 10.7124 0.845145C11.1231 1.21445 11.1566 1.84672 10.7873 2.25737C10.7542 2.29419 10.7184 2.32849 10.6802 2.36L6.68018 6.22C6.49731 6.39632 6.25419 6.49643 6.00018 6.5L6.00019 6.5Z" fill="#3B3EC9"/>
</svg>

Only gotcha

Since we're removing the height/width on the svg the dimensions we need to set the height/width now in css. For some the pixels are rendered much smaller than they actually are. This could be a bug or just my misundertanding of how svgs are rendered. We just need to handle height/width with its max counterpart.

width:100%;
max-width: 1rem;

Automagical Webpack Solution

I made a handy solution for webpack to do this for me with @svgr/webpack and some config options.

{
  test: /\.svg$/,
  use: [
    {
      loader: "@svgr/webpack",
      options: {
        svgoConfig: {
          plugins: [
            {
              removeDimensions: true,
              addAttributesToSVGElement: {
                attributes: [
                  {
                    preserveAspectRatio: "xMidYMid meet",
                  },
                ],
              },
            },
          ],
        },
      },
    },
  ],
}

Config Using React Svgr (kudos @guy-kdm)

.svgrrc file format:

{
  "expandProps": "start",
  "dimensions": "false",
  "svgProps": {
  "preserveAspectRatio": "xMidYMid meet",
  "fill": "currentColor",
  "className": "{'icon ' + (props.className || '')}"
  }
}

Credits:

@guy-kdm
Copy link

guy-kdm commented Aug 30, 2020

in .svgrrc format:
{
"expandProps": "start",
"dimensions": "false",

"svgProps": {
"preserveAspectRatio": "xMidYMid meet",
"fill": "currentColor",
"className": "{'icon ' + (props.className || '')}"
}
}

@myyellowshoe
Copy link
Author

@guy-kdm nice! Svgr is great. I'll add this.

@wgerro
Copy link

wgerro commented Nov 6, 2022

Great ! You saved my day :D This solution helped me reserveAspectRatio="xMidYMid meet"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment