英文:
How to render an external SVG file with the <use> tag?
问题
我正在尝试做一件我认为是一个非常简单的任务,但我就是无法让它工作。我已经完全复制了我在线找到的其他8个示例,就像这个一样,但都没有成功。
我实际上正在开发一个React项目,但为了让示例更简单,让我们将情况简化为以下内容:
我有一个名为svg的文件夹,其中包含svg.html和icon.svg。
svg.html 包含:
<html>
<head></head>
<body>
<svg>
<use href="icon.svg" />
</svg>
</body>
</html>
icon.svg 包含:
<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.5 0H2.5C1.4 0 0.5 0.9 0.5 2V16C0.5 17.1 1.4 18 2.5 18H16.5C17.6 18 18.5 17.1 18.5 16V2C18.5 0.9 17.6 0 16.5 0ZM2.5 16V2H8.5V16H2.5ZM16.5 16H10.5V9H16.5V16ZM16.5 7H10.5V2H16.5V7Z" fill="#9F9E99"/>
</svg>
当我运行这个html时,简单地什么都没有显示出来。我希望发生的是,icon.svg 在html中显示出来。我做错了什么?
英文:
I am trying to do something which I thought was a very simple task, but I just can't make it work. I have exactly copied about 8 other examples I found online, like this one, but to no avail.
I am actually working on a React project, but to make the example easier, let's reduce the situation to just this:
I have a folder called svg containing svg.html and icon.svg.
svg.html contains:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
<html>
<head></head>
<body>
<svg>
<use href="icon.svg" />
</svg>
</body>
</html>
<!-- end snippet -->
icon.svg contains:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.5 0H2.5C1.4 0 0.5 0.9 0.5 2V16C0.5 17.1 1.4 18 2.5 18H16.5C17.6 18 18.5 17.1 18.5 16V2C18.5 0.9 17.6 0 16.5 0ZM2.5 16V2H8.5V16H2.5ZM16.5 16H10.5V9H16.5V16ZM16.5 7H10.5V2H16.5V7Z" fill="#9F9E99"/>
</svg>
<!-- end snippet -->
When I run the html, simply nothing at all is displayed. What I want to happen, is for the icon.svg to be displayed in the html.
What am I doing wrong?
答案1
得分: 1
以下是翻译好的内容:
- 你可以将多个图标资源存储在外部的svg文件中。
- 使用
<symbol>
元素创建一个图标资源文件是一种常见的做法。 - 至关重要的是为所有的图标/符号赋予一个独特的ID。
- 现在你可以像这样引用每个图标:
<svg> <use href="icon.svg#symbolID" /> </svg>
- 覆盖图标样式时,应尽量保持图标样式属性的中性,即删除
fill
或style
属性,否则样式覆盖(例如从文本继承颜色或在悬停时更改填充)会变得更加复杂。
在上面的代码片段中,移除了所有的fill
属性,这样我们可以轻松地通过CSS规则fill: currentColor
来继承文本颜色。
-
带有单独
viewBox
设置的符号- 只在处理不同图标纵横比时需要,如果所有图标都相对于一个正方形(类似)的
viewBox
绘制,你可以直接设置图标的宽度和高度。 - 对于“比例”图标布局,为每个图标的
<symbol>
元素定义一个合适的viewBox
,并将这些值复制到包含<use>
引用元素的父级<svg>
元素中。
- 只在处理不同图标纵横比时需要,如果所有图标都相对于一个正方形(类似)的
-
外部图标svg应该托管在相同的域上
- 主要浏览器非常严格 - 即使你的图标svg托管在允许跨域访问的CDN上,除非你首先获取和内联文件,否则它不会工作。
- 正如Danny '365CSI' Engelman所评论的,你可以使用他的load-file本地Web组件。
- 你还可以使用keyamoon的"svgxuse"助手脚本。
- 重要提示:只有在允许跨域访问的服务器上托管的外部svg图标才能获取/注入!(例如,像svgshare这样的图像分享平台不会发送适当的CORS标头)。
-
替代方法:使用现有的图标库
- 创建自定义图标很棒,但也需要一些研究和大量的测试/调试。
- 因此,如果你对svg不是特别兴奋,最好选择一个现有的图标库,如fontAwesome、material icons等等。测试icomoon、fontello包括的库/导出功能(后者还可以导出svg文件)……列表还在不断扩展。
- 关键是:创建自己的自定义图标库通常并不是非常简单的事情 - 特别是混合来自不同来源的图标相当棘手。
在上述代码片段中,所有的fill
属性都被移除了。这样,我们可以通过CSS规则fill: currentColor
轻松继承文本颜色。
英文:
You can store multiple icon assets in an external svg file.
Create an icon asset file using <symbol>
elements
A common practice is to wrap your icons in a <symbol>
elements.
It is crucial to give all your icons/symbols a unique ID.
Now you can reference each icon like so:
<svg>
<use href="icon.svg#symbolID" />
</svg>
Overriding icon styles
Besides, you should keep your icon styles/style attributes as neutral as possible – so remove fill
or style
attributes – otherwise style overriding (e.g. inheriting colors from text or changing fills on hover) gets more complicated.
<!-- begin snippet: js hide: true console: true babel: false -->
<!-- language: lang-css -->
body{
font-size: 2em;
font-family: sans-serif
}
.icn-svg{
height:1em;
width:auto;
fill:currentColor;
}
.icn-svg-square{
height:1em;
width:1em;
}
<!-- language: lang-html -->
<p style="color:red">
<svg class="icn-svg" viewBox="0 0 19 18">
<use href="#customIcon" />
</svg>
Custom icom
</p>
<p style="color:green">
<svg class="icn-svg" viewBox="0 0 320 512">
<use href="#icon-chess-pawn" />
</svg>
fontAwesome icon proportional
</p>
<p style="color:purple">
<svg class="icn-svg icn-svg-square" >
<use href="#icon-calendar" />
</svg>
fontAwesome icon (square)
</p>
<!-- external icion.svg -->
<svg xmlns="http://www.w3.org/2000/svg" style="width:0;height:0;">
<symbol id="customIcon" viewBox="0 0 19 18" xmlns="http://www.w3.org/2000/svg">
<path d="M16.5 0H2.5C1.4 0 0.5 0.9 0.5 2V16C0.5 17.1 1.4 18 2.5 18H16.5C17.6 18 18.5 17.1 18.5 16V2C18.5 0.9 17.6 0 16.5 0ZM2.5 16V2H8.5V16H2.5ZM16.5 16H10.5V9H16.5V16ZM16.5 7H10.5V2H16.5V7Z" />
</symbol>
<symbol class="icon icon-chess-pawn" id="icon-chess-pawn" viewBox="0 0 320 512">
<path d="M296 463.1H23.1c-13.25 0-23.1 10.75-23.1 24s10.75 24 23.1 24h272c13.25 0 23.1-10.75 23.1-23.1S309.3 463.1 296 463.1zM55.1 287.1L80 287.1v29.5c0 40.25-3.5 81.25-23.38 114.5h53.5C125.1 394.1 128 354.6 128 317.5v-29.5h64v29.5c0 37.13 2.875 77.5 17.88 114.5h53.5C243.5 398.7 240 357.7 240 317.5V287.1l24-.0001C277.3 287.1 288 277.3 288 263.1c0-13.25-10.75-24-23.1-24H241c23.75-21.88 38.1-53.12 38.1-87.1c0-9.393-1.106-19.05-3.451-28.86C272.3 105.4 244.9 32 159.1 32C93.75 32 40 85.75 40 151.1c0 34.88 15.12 66.12 39 88H55.1C42.75 239.1 32 250.7 32 263.1C32 277.3 42.75 287.1 55.1 287.1zM160 79.1c39.75 0 72 32.25 72 72S199.8 223.1 160 223.1S88 191.7 88 151.1S120.2 79.1 160 79.1z"></path>
</symbol>
<symbol class="icon icon-calendar" id="icon-calendar" viewBox="0 0 448 512">
<path d="M152 64H296V24C296 10.75 306.7 0 320 0C333.3 0 344 10.75 344 24V64H384C419.3 64 448 92.65 448 128V448C448 483.3 419.3 512 384 512H64C28.65 512 0 483.3 0 448V128C0 92.65 28.65 64 64 64H104V24C104 10.75 114.7 0 128 0C141.3 0 152 10.75 152 24V64zM48 448C48 456.8 55.16 464 64 464H384C392.8 464 400 456.8 400 448V192H48V448z" />
</symbol>
</svg>
<!-- end snippet -->
We can't use external svgs in SO snippets. just replace the inline references to somethinng like icons.svg#customIcon
when running on local server.
In the above snippet, all fill attributes are removed.
This way we can easily inherit text colors via fill: currentColor
in a css rule like this:
.icn-svg{
height:1em;
width:auto;
fill:currentColor;
}
Symbols with individual viewBox
settings
Only needed, if you're dealing with different icon aspect ratios – if all icons are drawn relative to a square (like) viewBox – you can set the icons with and height directly.
For a "proportional" icon layout – define an appropriate viewBox
for each icon <symbol>
element and copy these values for the parent <svg>
elemnts containing your <use>
reference element.
External icon svgs should be hosted on same domain
Major browsers are very strict – even if your icon svg is hosted on a cdn allowing cross origin access, it won't work, unless you're fetching and inlining the file first.
As commented by Danny '365CSI' Engelman you could use his load-file native web component.
You might also use keyamoon's "svgxuse" helper script.
Important: you can only fetch/inject external svg icons if they are hosted on servers allowing cross origin access! (e.g image sharing platforms like svgshare don't send a suitable CORS header).
Alternative: use a existing icon library
Seriously, creating custom icons is great but also requires some research and quite a lot of testing/debugging.
So if you're not overly excited about svg, you should better opt for an existing icon library like fontAwesome, material icons ... test icomoon, fontello included libraries/export functions (the latter ones can also export svg files) ... the list goes on and on.
The point is: creating your own custom icon library is usually not very trivial – especially mixing icons from different sources is quite tricky.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论