簡體   English   中英

為什么 SVG 沒有<use>像普通 SVG 一樣標記比例?

[英]Why doesn't an SVG with a <use> tag scale like a regular SVG?

我有一個 SVG 圖標,我為它設置了一個固定的高度(比如 50 像素),但我希望它的寬度是自動的,也就是說,無論它需要什么都取決於圖標。 (很常見和正常的情況,對吧?)。

現在,我一直把頭撞在牆上的問題是,我打算用<symbol>標記定義它,然后使用<use href="...標簽,這樣做顯然需要我設置固定寬度和固定高度,否則它將始終默認為大約 150 像素,而不是僅默認為圖標的寬度;情況並非如此當您直接嵌入 SVG 時,您可以在以下兩個代碼段中看到所有這些操作:

直接嵌入SVG:(按預期工作,寬度與圖標寬度一致)

 .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>

但是使用<use>標簽:(寬度不知從何而來!)

 .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>

我已經簽出了這個問題,以及這一次,我已經意識到,通過添加的圖標引用SVG的“視框”,這個問題就迎刃而解了,就像這樣:

 .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>

但顯然這是非常不方便的,重復的,容易出錯的,而且寫起來確實很丑。 所以,我很感激任何解決方法。 有沒有辦法將 viewBox 屬性設置為“自動”或其他意味着“無論內部 SVG 是什么”,以避免每次要引用圖標時編寫(或復制粘貼) viewBox ?

老實說,我認為每個人都會直覺地期望它像常規嵌入式 SVG 一樣工作,因為viewBox已經在被引用的symbol上設置了一次。

我強烈推薦:

  • 使您的所有圖標具有一致的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>

然后在你的 CSS 中:

.icon {
  // as above
}

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

.icon.something-else {
  width: 35px;
  height: 50px;
}

只要您的圖標在其 viewBox 中水平居中,一切都會正常工作。

默認大小(方形)圖標不需要額外的 CSS。 您只需要為非方形的添加 CSS 規則。

如果您不反對使用某些 JavaScript,則以下方法應該可行。 加載一次,無論您的頁面上有多少個圖標。

 document.querySelectorAll(".icon").forEach(node => { const href = node.querySelector("use").href.baseVal; const icon = document.querySelector(href); const vb = icon.viewBox.baseVal; node.setAttribute("viewBox", `${vb.x} ${vb.y} ${vb.width} ${vb.height}`); });
 .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.133 a3.429,3.429,0,0,0-3.425,3.425V23.973A3.429,3.429,0,0,0,46.092,27.4 H62.074A3.429,3.429,0,0,0,65.5,23.973V12.557 A3.429,3.429,0,0,0,62.074,9.133Z m-13.7-1.142a5.708,5.708,0,0,1,11.416,0V9.133H48.375Z M63.216,23.973a1.143,1.143,0,0,1-1.142,1.142H46.092 a1.143,1.143,0,0,1-1.142-1.142V12.557a1.143,1.143,0,0,1,1.142-1.142 H62.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.922 a1.142,1.142,0,1,0,2.283,0v-1.922a3.416,3.416,0,0,0-1.142-6.639Z m0,4.566a1.142,1.142,0,1,1,1.142-1.142 A1.143,1.143,0,0,1,195.425,249.9Z" transform="translate(-192 -245.333)"> </path> </g> </g> </symbol> </svg> <svg class="icon"> <use href="#lock"></use> </svg>


如果您想動態添加圖標 - 在頁面加載后,以下內容也將比添加手動viewBox有所改進:

 function iconLoaded(event) { const node = event.target; const href = node.querySelector("use").href.baseVal; const icon = document.querySelector(href); const vb = icon.viewBox.baseVal; node.setAttribute("viewBox", `${vb.x} ${vb.y} ${vb.width} ${vb.height}`); }
 .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.133 a3.429,3.429,0,0,0-3.425,3.425V23.973A3.429,3.429,0,0,0,46.092,27.4 H62.074A3.429,3.429,0,0,0,65.5,23.973V12.557 A3.429,3.429,0,0,0,62.074,9.133Z m-13.7-1.142a5.708,5.708,0,0,1,11.416,0V9.133H48.375Z M63.216,23.973a1.143,1.143,0,0,1-1.142,1.142H46.092 a1.143,1.143,0,0,1-1.142-1.142V12.557a1.143,1.143,0,0,1,1.142-1.142 H62.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.922 a1.142,1.142,0,1,0,2.283,0v-1.922a3.416,3.416,0,0,0-1.142-6.639Z m0,4.566a1.142,1.142,0,1,1,1.142-1.142 A1.143,1.143,0,0,1,195.425,249.9Z" transform="translate(-192 -245.333)"> </path> </g> </g> </symbol> </svg> <svg class="icon" onload="iconLoaded(event)"> <use href="#lock"></use> </svg>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM