Cross-browser embedded font in svg image
The title is ambiguous; let me clarify: I have an svg image which includes a text I want rendered with a custom font.
However, there seem to be new issues that do not pop up when embedding fonts in html page. Also, some browsers (namely Firefox) seem to treat in-page svg ("in a img
tag") differently than when rendering the svg directly.
<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');
}
/* ...
As far as I know, if this was a web page it would render successfully across pretty much everywhere. However, as an svg, I can't get it to work. The current format works pretty much everywhere except in IE10 (and presumably older versions): the font sometimes loads, other time it doesn't. Literally every second refresh uses the system fallback font. Including the woff file inline as a base64 encoded file works, but that breaks it for Safari (and changing order does not fix it).
Is there a solid way of cross browser embedded fonts in svg image? (Again, I don't mean embedding svg font in a web page, but rendering embedded font inside an svg image.)
In Firefox at least, images must be completely self-contained i.e. everything in one file for privacy reasons.
If you want the fonts to work you'll have to base64 encode them and embed them as a data URLs in the SVG file i.e.
@font-face {
font-family: 'Open Sans';
src: url("data:application/x-font-ttf;base64,[base-encoded font here]");
}
I ended up using this:
<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>
Support:
+------------+--------+-------+-------+-----------+
| | 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 | | | |
+------------+--------+-------+-------+-----------+
Per http://gs.statcounter.com/#browser_version_partially_combined-ww-monthly-201310-201312-bar this amounts for overall support of somewhere around 85 %.
The only really bothering thing is that Safari 5.1 renders NO text at all like this. I had to make a Safari only fallback in the css declaration:
/* Win Safari fallback */
@media screen and (-webkit-min-device-pixel-ratio:0) {
/* Safari only */
::i-block-chrome,text {
font-family: 'Verdana';
}
}
Anyway, embedding the font just feels wrong as the files are huge.