为什么带有 <use> 标签的 SVG 不像普通 SVG 那样缩放?

Ami*_*adi 2 html css svg

我有一个 SVG 图标,我为它设置了一个固定的高度(比如 50 像素),但我希望它的宽度是自动的,也就是说,无论它需要什么都取决于图标。(很常见和正常的情况,对吧?)。

现在,我一直把头撞在墙上的问题是,我打算用<symbol>标签定义它,然后使用<use href="...标签引用它,而不是将 SVG 内联嵌入到 HTML 中,然后这样做显然需要我设置一个固定的宽度和一个固定的高度,否则它总是默认为大约 150px,而不是仅仅默认为图标的宽度;当您直接嵌入 SVG 时,情况并非如此,您可以在以下两个片段中看到所有这些都在起作用:

直接嵌入SVG:(按预期工作,宽度与图标的宽度一致)

.icon {
  height: 50px;
  width: auto;

  /* Aesthetics: */
  background-color: gray;
  border-radius: 5px;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

但是使用<use>标签:(宽度不知从何而来!)

.icon {
  height: 50px;
  width: auto;

  /* Aesthetics: */
  background-color: gray;
  border-radius: 5px;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

我已经签出了这个问题,以及这一次,我已经意识到,通过添加的图标引用SVG的“视框”,这个问题就迎刃而解了,就像这样:

.icon {
  height: 50px;
  width: auto;

  /* Aesthetics: */
  background-color: gray;
  border-radius: 5px;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

但显然这是非常不方便的,重复的,容易出错的,而且写起来确实很丑。所以,我很感激任何解决方法。有没有办法将 viewBox 属性设置为“自动”或表示“无论内部 SVG 是什么”的东西,以避免viewBox每次要引用图标时写入(或复制粘贴)?

老实说,我认为每个人都会直觉地希望它像常规的嵌入式 SVG 一样工作,因为viewBox已经在symbol被引用的SVG 上设置了一次。

Pau*_*eau 5

我强烈推荐:

  • 使您的所有图标具有一致的viewBox. 例如, "0 0 24 24"是许多图标库使用的常见图标。这样你就不必viewBox在你需要的地方找到并复制正确的。它总是"0 0 24 24"

  • 将类添加到<svg>可用于设置图标宽度的引用。

<svg class="icon lock" viewBox="0 0 24 24">
  <use href="#lock"></use>
</svg>
Run Code Online (Sandbox Code Playgroud)

然后在你的 CSS 中:

.icon {
  // as above
}

.icon.lock {
  width: 45px;
  height: 50px;
}

.icon.something-else {
  width: 35px;
  height: 50px;
}
Run Code Online (Sandbox Code Playgroud)

只要您的图标在其 viewBox 中水平居中,一切都会正常工作。

默认大小(方形)图标不需要额外的 CSS。您只需要为非方形的添加 CSS 规则。