在 SVG 中使用自定义字体
🏷️ SVG
今天通过 Excalidraw 画了一个 JVM 的内存架构图,但是当放到博客中时,字体的样式没有起作用。
打开 SVG 图片可以看到类似如下的字体样式定义:
<defs>
<style class="style-fonts">
@font-face {
font-family: "Virgil";
src: url("https://excalidraw.com/Virgil.woff2");
}
@font-face {
font-family: "Cascadia";
src: url("https://excalidraw.com/Cascadia.woff2");
}
</style>
</defs>
在浏览器的标签中单独打开 SVG 图片时,可以正确的显示字体,但是当把 SVG 图片放入到网页中显示时,浏览器并不会加载自定义的字体。
之所以这样是出于安全的考虑,大多数浏览器不允许通过 <img>
标签加载外部资源。 [1]
下面的 No.1 ~ 4 使用 <img>
标签测试了几种 SVG 的显示效果,No.5 ~ 7 则是分别使用 <object>
、<embed>
、<svg>
将 SVG 图片的内容嵌入到了当前页面。另外还可以使用 <iframe>
和 CSS 的 background-image
。 [2]
Excalidraw 导出的原图
SVG 图片没有应用自定义的字体,但是在单独的标签中打开时字体是对的。
通过 Nano 压缩后的 SVG 文件
效果和原图一样,只是文件变小了。本以为 Nano 会自动将引用的字体提取出来,结果并没有。
从原 SVG 文件中删除了字体定部分
本以为会自动使用页面样式中的字体,但其实并没有。
Font Family -- Virgil -- Sample
SVG 中直接嵌入 base64 格式的字体,并使用 Nano 压缩后的图
这种方式字体显示始终是对的,但是文件相对较大。
Woff2 字体转 base64 工具:Woff2Base 。
使用
<object>
标签嵌入 SVG 文件字体显示也是对的。
使用这种嵌入 SVG 的方式时没法使用轮播插件。不知道有没有支持这种嵌入式 SVG 的轮播插件。
html<object type="image/svg+xml" data="jvm-memory.svg"></object>
使用
<embed>
标签嵌入 SVG 文件和
<object>
标签效果类似。不要使用这个标签。虽然很多浏览器都支持,但是这个标签主要用于实现 Flash 插件等。[2:1]
html<embed type="image/svg+xml" src="jvm-memory.svg">
将 SVG 文件直接嵌入到网页中
此时 SVG 已变成当前页面的元素,直接使用
@font-face
注册字体即可。这种样式貌似不大好控制,图片会显示成原始的尺寸,这里由于设置了最大宽度,所以没有显示全。
html<style class="style-fonts"> @font-face { font-family: "Virgil"; src: url("https://excalidraw.com/Virgil.woff2"); } </style> <svg xmlns="http://www.w3.org/2000/svg" width="981.134" height="745.892" xmlns:v="https://vecta.io/nano" ... </svg>