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.
- use an image tag
- use wrappers
- use weird padding
- pass down props for width/height or viewBox props.
- Preserve Aspect Ratio
- Be able to modify my svg via css
- Provide width/height and have svg scale automatically.
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>
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;
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",
},
],
},
},
],
},
},
},
],
}
.svgrrc
file format:
{
"expandProps": "start",
"dimensions": "false",
"svgProps": {
"preserveAspectRatio": "xMidYMid meet",
"fill": "currentColor",
"className": "{'icon ' + (props.className || '')}"
}
}
Credits:
@guy-kdm nice! Svgr is great. I'll add this.