[英]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.