问题 svg图像中的跨浏览器嵌入字体


标题含糊不清;让我澄清一下:我有一个svg图像,其中包含我想用自定义字体渲染的文本。

但是,在html页面中嵌入字体时似乎没有出现新问题。此外,一些浏览器(即Firefox)似乎处理页内svg(“在一个 img 标记“)与直接渲染svg时不同。

<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图像中渲染嵌入字体。)


10042
2018-01-03 13:42


起源

尝试这个 nimbupani.com/about-fonts-in-svg.html - mcmac


答案:


至少在Firefox中,图像必须是完全自包含的,即一个文件中的所有内容 出于隐私原因

如果你想让字体工作,你必须对它们进行base64编码并将它们作为数据URL嵌入到SVG文件中,即

@font-face {
    font-family: 'Open Sans';
    src: url("data:application/x-font-ttf;base64,[base-encoded font here]");
}

8
2018-01-03 14:50



谢谢,这就是我的所作所为。但是正如我上面提到的,这似乎不适用于iOS(因为它遇到的任何base64都会破坏它)。将再次检查以确保。 - Mikulas Dite
我只知道Firefox是如何工作的;-) - Robert Longson
对于IE,如果你做除了ttf以外的任何事情,它会中断。 Chrome和fox与ttf(以及woff / woff2)配合使用效果很好 - Aaron Sherman


我最终使用了这个:

<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';
    }
}

无论如何,嵌入字体只是感觉错误,因为文件很大。


4
2018-01-03 19:07



比多个请求更大的文件。 - Frederik Krautwald
虽然这通常是正确的,我的原始应用程序在GitHub上提供CI徽章,这意味着有成千上万的无法访问的svgs,每个只有一百个字节。由于字体缓存很好,因此在这种情况下嵌入它将是一个巨大的浪费。 - Mikulas Dite