I have an SVG icon, I'm setting a fixed height for it (50px, say), but I want its width to be auto, that is, whatever it needs to be depending on the icon. (Pretty common and normal scenario, right?).
Now, the problem that I've been beating my head against the wall for, is that instead of embedding the SVG inline in the HTML, I'm intending to define it with the <symbol>
tag and then reference it using the <use href="...
tag, and doing so apparently requires me to set a fixed width as well as a fixed height or otherwise it will always default to about 150px, instead of just defaulting to the width of icon; this is not the case when you embed the SVG directly, you can see all of this in action in the following two snippets:
Directly-embedded SVG: (Works as expected, width is consistent with the width of the icon)
.icon {
height: 50px;
width: auto;
/* Aesthetics: */
background-color: gray;
border-radius: 5px;
}
<svg class="icon" viewBox="0 0 22.832 27.398">
<g transform="translate(-42.667)"> <g transform="translate(42.667)"> <path class="a" d="M62.074,9.133V7.991a7.991,7.991,0,1,0-15.982,0V9.133a3.429,3.429,0,0,0-3.425,3.425V23.973A3.429,3.429,0,0,0,46.092,27.4H62.074A3.429,3.429,0,0,0,65.5,23.973V12.557A3.429,3.429,0,0,0,62.074,9.133Zm-13.7-1.142a5.708,5.708,0,0,1,11.416,0V9.133H48.375ZM63.216,23.973a1.143,1.143,0,0,1-1.142,1.142H46.092a1.143,1.143,0,0,1-1.142-1.142V12.557a1.143,1.143,0,0,1,1.142-1.142H62.074a1.143,1.143,0,0,1,1.142,1.142Z" transform="translate(-42.667)"></path> </g> <g transform="translate(50.658 13.128)"> <path class="a" d="M195.425,245.333a3.416,3.416,0,0,0-1.142,6.639v1.922a1.142,1.142,0,1,0,2.283,0v-1.922a3.416,3.416,0,0,0-1.142-6.639Zm0,4.566a1.142,1.142,0,1,1,1.142-1.142A1.143,1.143,0,0,1,195.425,249.9Z" transform="translate(-192 -245.333)"></path> </g> </g>
</svg>
But using the <use>
tag: (Width is coming from nowhere!)
.icon {
height: 50px;
width: auto;
/* Aesthetics: */
background-color: gray;
border-radius: 5px;
}
<svg style="display: none;">
<symbol id="lock" viewBox="0 0 22.832 27.398">
<g transform="translate(-42.667)"> <g transform="translate(42.667)"> <path class="a" d="M62.074,9.133V7.991a7.991,7.991,0,1,0-15.982,0V9.133a3.429,3.429,0,0,0-3.425,3.425V23.973A3.429,3.429,0,0,0,46.092,27.4H62.074A3.429,3.429,0,0,0,65.5,23.973V12.557A3.429,3.429,0,0,0,62.074,9.133Zm-13.7-1.142a5.708,5.708,0,0,1,11.416,0V9.133H48.375ZM63.216,23.973a1.143,1.143,0,0,1-1.142,1.142H46.092a1.143,1.143,0,0,1-1.142-1.142V12.557a1.143,1.143,0,0,1,1.142-1.142H62.074a1.143,1.143,0,0,1,1.142,1.142Z" transform="translate(-42.667)" /> </g> <g transform="translate(50.658 13.128)"> <path class="a" d="M195.425,245.333a3.416,3.416,0,0,0-1.142,6.639v1.922a1.142,1.142,0,1,0,2.283,0v-1.922a3.416,3.416,0,0,0-1.142-6.639Zm0,4.566a1.142,1.142,0,1,1,1.142-1.142A1.143,1.143,0,0,1,195.425,249.9Z" transform="translate(-192 -245.333)" /> </g> </g>
</symbol>
</svg>
<svg class="icon">
<use href="#lock"></use>
</svg>
I've already checked out this question, as well as this one, and I've realized that by adding the "viewBox" of the icon to the referencing SVG, the problem would be solved, like this:
.icon {
height: 50px;
width: auto;
/* Aesthetics: */
background-color: gray;
border-radius: 5px;
}
<svg style="display: none;">
<symbol id="lock" viewBox="0 0 22.832 27.398">
<g transform="translate(-42.667)"> <g transform="translate(42.667)"> <path class="a" d="M62.074,9.133V7.991a7.991,7.991,0,1,0-15.982,0V9.133a3.429,3.429,0,0,0-3.425,3.425V23.973A3.429,3.429,0,0,0,46.092,27.4H62.074A3.429,3.429,0,0,0,65.5,23.973V12.557A3.429,3.429,0,0,0,62.074,9.133Zm-13.7-1.142a5.708,5.708,0,0,1,11.416,0V9.133H48.375ZM63.216,23.973a1.143,1.143,0,0,1-1.142,1.142H46.092a1.143,1.143,0,0,1-1.142-1.142V12.557a1.143,1.143,0,0,1,1.142-1.142H62.074a1.143,1.143,0,0,1,1.142,1.142Z" transform="translate(-42.667)" /> </g> <g transform="translate(50.658 13.128)"> <path class="a" d="M195.425,245.333a3.416,3.416,0,0,0-1.142,6.639v1.922a1.142,1.142,0,1,0,2.283,0v-1.922a3.416,3.416,0,0,0-1.142-6.639Zm0,4.566a1.142,1.142,0,1,1,1.142-1.142A1.143,1.143,0,0,1,195.425,249.9Z" transform="translate(-192 -245.333)" /> </g> </g>
</symbol>
</svg>
<svg class="icon" viewBox="0 0 22.832 27.398"> <!-- Copy-pasted the viewbox here -->
<use href="#lock"></use>
</svg>
But obviously this is very inconvenient, repetitive, error-prone, and indeed ugly to write. So, I'd appreciate any workarounds. Isn't there a way to set the viewBox attribute to "auto" or something which means "whatever the inner SVG is", so as to avoid writing (or copy-pasting, rather) the viewBox
each time you want to reference an icon?
To be honest, I think everyone would intuitively kind of expect this to work like regular embedded SVGs since the viewBox
is already set once on the symbol
that is being referenced.