svg @font-face works in svg but not when included in a page

romeovs picture romeovs · Dec 13, 2013 · Viewed 18.4k times · Source

I've got an svg file which includes a certain font using the @font-face syntax. This svg is located at /logo/logo-big-web.svg and the font is in /font/MDN/MDN.ttf on the server.

Everything works fine when I open http://www.mywebsite/logo/logo-big-web.svg in a browser the font loads properly and the svg file is displayed correctly.

However, when I try to embed the svg file in a html file, for instance in index.html:

<img src="/logo/logo-big-web.svg" ... ></img>

When I open http://www.mywebsite/index.html in a browser, the font does not load properly and the svg displays an ugly default font.

Has anyone else experienced this problem? How does one get around it?

I know I could embed the font as svg glyphs inside the svg file, but this doesn't work in firefox and adds a lot to the filesize of the svg while I'm loading the font anyways for use on the webpage itself (it seems wasteful to load the font twice). So embedding the glyphs is no option. Same goes for embedded data: uri.

Update:

The font is specified in the svg file as:

<defs>
    <style>
        @font-face {
            font-family: MDN;
            src: url("/font/MDN/MDN.ttf"); }
    </style>
</defs>

and I use it as follows:

<text font-family="MDN" font-size="11"> <textPath ... > ... </textPath> </text>

Update 2:

I tried to circumvent the problem by defining the font in a separate stylesheet, and include it like this:

<?xml-stylesheet type="text/css" href="/style/slyle.css" ?>

But this seems to have the same problem: It works when I open the svg directly in a browser (http://www.mywebsite/logo/logo-big-web.svg) but breaks down when I use the svg in a html img tag or as a background to a html element.

Answer

romeovs picture romeovs · Dec 14, 2013

According to this answer to a related question, embedded svg images have to be standalone images. As mentioned in the comments above, one can make an svg 'standalone' by embedding all external assets into it. So in my case, i'd have to do either one of these things:

  1. embed the fonts using a data uri: src: url("data:application/font-woff;base64,<base64 encoded font here"),
  2. embed the fonts as svg glyphs, which I had already ruled out because the lack of firefox support
  3. turn the fonts into paths in my editing software (e.g. expand path in adobe illustrator).

Not one of these methods seemed satisfactory, since I really like to keep the svg files as lightweight as possible.

Another solution to circumvene the whole problem is to use a html object tag instead of an img tag. This way the svg is allowed to be more than a standalone image and it can use the full range of xml inclusion methods to include other assets. This was pointed out already in the aforementioned question.

I chose to use the object method of embedding the svg. I'll update this answer if I find out there is something fundamentally wrong with doing this instead of using a proper img element.