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.