跨浏览器嵌入字体在SVG图像中

12
标题有歧义,让我来澄清一下:我有一个 SVG 图像,其中包含一段文字,我想用自定义字体渲染它。然而,在嵌入 HTML 页面中时会出现一些新的问题。此外,一些浏览器(尤其是 Firefox)在渲染直接呈现 SVG 和在页面内使用 SVG(例如在img标签中)时表现不同。
<defs>
<style>
    @font-face {
        font-family: "Open Sans";
        src: local("Open Sans"),
            local("OpenSans"),
            url('https://example.com/OpenSans-Regular.eot') format('eot'),
            url('https://example.com/OpenSans-Regular.woff') format('woff'),
            url('https://example.com/OpenSans-Regular.ttf') format('truetype');
    }
    /* ...
据我所知,如果这是一个网页,它应该可以成功地在几乎所有的地方进行呈现。然而,作为svg图片,我无法让它正常工作。当前格式在几乎所有地方都能正常工作,除了IE10(和可能的旧版本):字体有时会加载,有时不会。每隔一秒刷新就会使用系统替代字体。将woff文件以base64编码文件的形式嵌入内部可以解决问题,但这样会破坏Safari的功能(改变顺序也无法解决问题)。
是否有一种可靠的方法来在svg图像中嵌入跨浏览器的字体?(再次强调,我指的是在svg图像中呈现嵌入的字体,而不是将svg字体嵌入网页中。)

试试这个链接:http://nimbupani.com/about-fonts-in-svg.html - mcmac
2个回答

9
在Firefox浏览器中,图片必须完全自包含,也就是说,所有内容都必须在一个文件中出于隐私原因
如果您希望字体能够正常工作,就需要将它们进行base64编码,并将其嵌入SVG文件中,即使用数据URL。
@font-face {
    font-family: 'Open Sans';
    src: url("data:application/x-font-ttf;base64,[base-encoded font here]");
}

谢谢,那就是我做的。然而正如我上面所指出的,这在iOS上似乎不起作用(因为它遇到的任何base64都会中断它)。不过我会再次检查以确保。 - Mikulas Dite
对于IE,除了使用ttf之外的任何其他操作都会导致出现问题。Chrome和Firefox在使用ttf(以及woff/woff2)方面效果很好。 - Aaron Sherman

5
我最终使用了这个:

我最终使用了这个:

<defs>
<style type="text/css">
<![CDATA[    @font-face {        font-family: "Open Sans";        src: local("Open Sans"), /* IE */            local("OpenSans"),            url("data:application/vnd.ms-fontobject;charset=utf-8;base64,{$fontEot}") format('embedded-opentype'),            url("data:application/x-font-woff;charset=utf-8;base64,{$fontWoff}") format('woff'),            url('https://example.com/OpenSans-Regular.ttf') format('truetype');    }]]>
</style>

支持:

+------------+--------+-------+-------+-----------+
|            | Win XP | Win 7 | iOS 6 | OS X 10.9 |
+------------+--------+-------+-------+-----------+
| IE  8      |     no |    no |       |           |
| IE  9      |        |   yes |       |           |
| IE 10      |        |   yes |       |           |
| IE 11      |        |   yes |       |           |
| Safari 4   |        |   yes |       |           |
| Safari 5.0 |        |   yes |       |           |
| Safari 5.1 |        |    no |       |           |
| Safari 7   |        |    no |       |       yes |
| Safari iOS |        |       |   yes |           |
| FF  3.6    |     no |    no |       |           |
| FF  4      |    yes |   yes |       |           |
| FF 27      |    yes |   yes |       |       yes |
| Chrome 14  |    yes |   yes |       |           |
| Chrome 33  |    yes |   yes |       |       yes |
| Opera 10.6 |    yes |   yes |       |           |
| Opera 19   |    yes |       |       |           |
+------------+--------+-------+-------+-----------+

根据http://gs.statcounter.com/#browser_version_partially_combined-ww-monthly-201310-201312-bar,这大约占总支持率的85%。

唯一令人困扰的是Safari 5.1完全不呈现文本。我不得不在css声明中添加一个仅适用于Safari的后备方案:

/* Win Safari fallback */
@media screen and (-webkit-min-device-pixel-ratio:0) { 
    /* Safari only */
    ::i-block-chrome,text {
        font-family: 'Verdana';
    }
}

无论如何,嵌入字体都感觉不对,因为文件太大了。

2
比起多次请求,使用较大的文件更为优越。 - Frederik Krautwald
1
虽然这通常是正确的,但我的原始应用程序是在GitHub上提供CI徽章,这意味着有数千个未缓存的SVG,每个只有一百字节。由于字体可以很好地缓存,因此在这种情况下嵌入它将是巨大的浪费。 - Mikulas Dite

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接