75

I'm writing an article on my site about the advantages of new web technologies, among others HTML5, CSS3 and SVGs, one of the advantages of the latter being the ability to select text in what is otherwise effectively an image.

I'm new to SVGs, and just made my first decent graphic in Illustrator. I've embedded it into a page with the GWF script for the Ubuntu font in the tag. As it turns out, the Ubuntu font displays correctly in regular text, but for this trick to work in the SVG, the Google script has to be embedded in the SVG itself. How can I do this?

1
  • 1
    One important note regarding the @import based solutions: they don't work for background-images. You must embed the font via base64 or use an image/object tag instead.
    – Mickey
    Commented Feb 23, 2017 at 20:25

9 Answers 9

56

You embed fonts in CSS by using base64 encoding. You can apply styles in SVG documents similar to CSS by using a <style /> element. So if you have a WOFF font, you'd embed it like this:

<style>
@font-face {
    font-family: "Sample font";
    src: url("data:application/font-woff;charset=utf-8;base64,...");
}
</style>

Where ... is the base64 encoded font data.

You can find examples of this by looking at Typekit's stylesheets. I'm not sure if the mime type of font/woff is correct, as I've also seen people claim that it should be application/font-woff. Though font/woff, font/truetype, font/opentype, etc. seem to be more popular.

Alternatively, you could actually take the SVG version of the web font and embed the SVG font's description markup inside of your document (though browser support is still very limited as Luke notes in the comments).

However, you should also be able to link to an external font according to the SVG specification. That would seem to be the best solution if you're gonna have multiple SVG documents referencing that font.

6
  • 3
    Regarding "you could actually take the SVG version of the web font and embed the SVG font's description markup inside of your document", you should be aware that "SVG Fonts are currently supported only in Safari and Android Browser." See developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/SVG_fonts (also caniuse.com/#feat=svg-fonts)
    – Luke
    Commented Jan 13, 2015 at 20:29
  • 2
    This thread helped a lot, but the question then became how to convert a font to base64. This site transfonter.org helped a lot and allows one to pick only a subset of the font to be converted, so as to reduce file size. Commented Dec 3, 2016 at 8:03
  • 1
    This answer looked tempting, but ultimately I found these steps to be easier, so I shared them: graphicdesign.stackexchange.com/a/124900/45239
    – Ryan
    Commented May 24, 2019 at 11:17
  • When I am opening that svg in adobe illustrator, fonts are not loading. Any help? Commented Oct 3, 2019 at 7:26
  • 1
    I've had success with data:application/font-woff2;charset=utf-8;base64, Commented Jan 15, 2021 at 5:25
21

A <defs> section like

<defs>
  <style type="text/css">@import url(http://fonts.googleapis.com/css?family=Indie+Flower);</style>
</defs>

works.

5
  • 16
    In current (February 2016) web browsers, this works only when loading the SVG file stand-allone. See marians.github.io/test-webfonts-in-svg/test.svg for an example. Opening the same SVG within an HTML page, the font is not loaded/rendered. Use marians.github.io/test-webfonts-in-svg as an example.
    – Marian
    Commented Feb 16, 2016 at 13:40
  • 1
    Both stand-alone SVG and HTML page seem to work the same in Chrome Version 73.0.3683.103 (Official Build) (64-bit).
    – Paul Grime
    Commented Apr 18, 2019 at 8:47
  • It's loading fonts when I open svg on browser, but when I open the same svg file in Adobe Illustrator, it's not loading fonts. Any help? Commented Oct 2, 2019 at 12:25
  • @AamirNakhwa you will need to download the Google Font to your local computer before it displays properly in Illustrator
    – clayRay
    Commented Jan 9, 2020 at 0:51
  • 1
    @Marian links are broken Commented Mar 11, 2020 at 10:27
9

You can embed Google Web Fonts into your SVG directly using Nano. It automatically scans your SVG and selectively embed only the fonts required, ensuring that your Ubuntu fonts look the same on all modern browsers. In my case, I needed Roboto to be embedded in my SVG:

enter image description here

Disclaimer: I'm with the team behind Nano, and we too, have faced the same problem previously hence decided to scratch our own itch by building Nano. Hope this is helpful!

Edit: Here's a quick explanation on what happens behind the scene:

To embed fonts in SVG, you first have to know what font families are used. Then you need to find these font files and download them. Once downloaded, you have to convert regular, bold, italics and bold italics to base 64 encoding. If you're doing it manually, it is a huge amount of work, over a large number of files, to know which file uses bold and which ones does not. Then you have to copy all 4 base 64 encoded strings into your SVG.

That's why we build Nano and make sure it scans SVG automatically and insert only the fonts being used. For example, if bold is not used or if no text exist, then no fonts will be embedded. All you need to do is drag and drop your SVG into Nano and it works like a charm! You can learn more here: https://vecta.io/blog/making-svg-easier-to-use

1
  • OK, great looks good. Unfortunately uploading to a Wordpress site that was quite happy to accept the SVG before now will not "Sorry, this file type is not permitted for security reasons." - what do I need to put back to make this work?
    – Chris Pink
    Commented Jun 20, 2019 at 16:31
4

UPDATE to my answer. I now prefer a different answer on this page, which is to use Nano: https://graphicdesign.stackexchange.com/a/121950/45239

Assuming you've downloaded and installed a web font on your system and have created an SVG (maybe using a lot of the same steps as I describe below but not choosing "Font: Convert To Outlines"), you can upload the SVG to Nano and see the "Embed font: Yes" option, and click Download.

My previous answer:

If you're willing to sacrifice having selectable text and SEO:

  1. Download the web font.
  2. Install it locally.
  3. Open Adobe Illustrator
  4. Type your text.
  5. File > Export > Export As…
  6. Choose ".SVG"
  7. Choose these settings:

    • Styling: Inline Style
    • Font: Convert To Outlines
    • Images: Preserve
    • Object IDs: Layer Names
    • Decimal: 2
    • (enabled) Minify
    • (enabled) Responsive
  8. Optionally upload the resulting svg to https://vecta.io/nano (It was able to reduce my file size by 8.2%)

3
  • Unfortunately 'convert to outlines' is not a great option for smaller text sizes.
    – Chris Pink
    Commented Jun 20, 2019 at 16:20
  • @ChrisPink, yes you are right !, Please share if you have found any other option for small font size Commented Jul 25, 2019 at 11:51
  • 1
    @SuperModel I used Nano with great success, with the fonts picking up styles from the enclosing document. My first attempts failed but with the kind help of the Nano team we worked out it was a case of making sure the SVG header stayed intact.
    – Chris Pink
    Commented Aug 1, 2019 at 10:05
3

Next to Nano you can also check out svg-buddy. That's a command line tool that automatically detects the used fonts in your SVG, downloads them from Google Fonts and embeds the base64-encoded fonts in the defs tag of the SVG. This ensures that the SVG is displayed the same way on all devices independent of the installed fonts on the user's system. Moreover, svg-buddy can also apply some basic optimization to reduce the file size. It's totally free and works offline.

Disclaimer: I'm the author of this open-source tool. I hope that it's useful for others.

2

This may be over simplifying, but have you considered downloading the font as a zip file from google and then letting Illustrator convert it as needed into your SVG file output?

This is only theoretical as I haven't tried this yet, but in theory would seem to work.

0

Add the following after <desc> tag

<defs>
<style type="text/css">@import url('http://fonts.googleapis.com/css?family=Lobster|Fontdiner+Swanky|Crafty+Girls|Pacifico|Satisfy|Gloria+Hallelujah|Bangers|Audiowide|Sacramento');</style>
</defs>
3
  • why include so many google fonts? It's not even all of them or the most used I see a lot and will add to SVG overall weight.
    – MrMesees
    Commented Apr 7, 2017 at 7:29
  • 1
    It's loading fonts when I open svg on browser, but when I open the same svg file in Adobe Illustrator, it's not loading fonts. Any help? Commented Oct 2, 2019 at 12:29
  • @AamirNakhwa intuitively, Illustrator may not be compliant with some parts of the CSS spec, or may block requests to external domains. @import is in both of those buckets.
    – Jules
    Commented Aug 17, 2020 at 17:35
0

I was able to fix the problem by, instead of using the SVG as a source of an image in the HTML file, I inserted the SVG inline in the HTML itself.

Ex: (Did not work)

<img src="/img/my_svg.svg">

I needed to put the actual SVG inside of the HMTL file itself. Then, Safari was able to read the fonts that I had previously imported.

Ex: (Works)

<svg class="coupon" height="220.254" viewBox="0 0 434.842 220.254" width="434.842" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <linearGradient id="a" gradientUnits="objectBoundingBox" x1=".079" x2=".933" y1=".088" y2=".879">
        <stop offset="0" stop-color="#00b2dc"/>
        <stop offset="1" stop-color="#00dac4"/>
    </linearGradient>
    <path d="m281.406 302.474a6.213 6.213 0 0 1 -6.167-6.914l.726-6.415a15.2 15.2 0 0 0 .1-1.7 14.846 14.846 0 0 0 -14.817-14.845c-.461 0-.915.026-1.364.066l-6.275.565a6.21 6.21 0 0 1 -6.763-6.189v-149.4a6.209 6.209 0 0 1 6.762-6.189l6.275.563c.451.04.906.068 1.366.068a14.846 14.846 0 0 0 14.819-14.839 15.225 15.225 0 0 0 -.1-1.7l-.726-6.415a6.212 6.212 0 0 1 6.167-6.912h365.712a6.211 6.211 0 0 1 6.167 6.912l-.724 6.415a15.316 15.316 0 0 0 -.1 1.7 14.844 14.844 0 0 0 14.818 14.839c.461 0 .917-.028 1.366-.068l6.277-.563a6.209 6.209 0 0 1 6.761 6.189v149.4a6.211 6.211 0 0 1 -6.763 6.189l-6.277-.565c-.449-.04-.9-.066-1.364-.066a14.844 14.844 0 0 0 -14.818 14.837 15.316 15.316 0 0 0 .1 1.7l.724 6.415a6.212 6.212 0 0 1 -6.167 6.914z" fill="#fff" transform="translate(-246.845 -82.22)"/>
    <path d="m661.315 118.088a26.8 26.8 0 0 1 -26.785-26.82 27.426 27.426 0 0 1 .176-3.048h-352.816a27.448 27.448 0 0 1 .176 3.048 26.8 26.8 0 0 1 -26.785 26.821c-.822 0-1.634-.042-2.435-.114v136.777c.8-.074 1.614-.116 2.435-.116a26.8 26.8 0 0 1 26.785 26.823 27.477 27.477 0 0 1 -.176 3.048h352.816a27.455 27.455 0 0 1 -.176-3.048 26.8 26.8 0 0 1 26.785-26.823c.822 0 1.634.042 2.435.116v-136.777c-.802.072-1.614.113-2.435.113z" fill="url(#a)" transform="translate(-240.878 -76.237)"/>
    <g fill="#fff">
        <path d="m621.645 274.026h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.975v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.968zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-17.291-.859a33.59 33.59 0 0 0 -2.734-9.267l1.811-.835a35.522 35.522 0 0 1 2.888 9.824zm341.224-7.679-1.851-.741a35.833 35.833 0 0 1 5.1-8.866l1.568 1.232a33.823 33.823 0 0 0 -4.823 8.375zm-349.198-9.708a34.131 34.131 0 0 0 -7.31-6.315l1.075-1.682a36.025 36.025 0 0 1 7.739 6.687zm360.994-5.343-1.159-1.628a35.748 35.748 0 0 1 9.083-4.7l.652 1.891a33.621 33.621 0 0 0 -8.577 4.437zm-377.09-4.959a33.483 33.483 0 0 0 -3.979-.891l-.84-.138v-6.629h1.994v4.939c1.137.21 2.27.479 3.377.8zm392.125-5.88h-1.995v-9.986h1.995zm-394.949-11.763h-1.994v-9.986h1.994zm394.949-8.209h-1.995v-9.986h1.995zm-394.949-11.764h-1.994v-9.986h1.994zm394.949-8.209h-1.995v-9.986h1.995zm-394.949-11.763h-1.994v-9.99h1.994zm394.949-8.209h-1.995v-9.981h1.995zm-394.949-11.763h-1.994v-9.986h1.994zm394.949-8.209h-1.995v-9.986h1.995zm-394.949-11.763h-1.994v-9.986h1.994zm394.949-8.209h-1.995v-9.986h1.995zm-394.949-11.763h-1.994v-6.679l.84-.134a33.762 33.762 0 0 0 3.935-.881l.551 1.919c-1.1.316-2.214.577-3.331.787zm391.395-5.313a35.649 35.649 0 0 1 -9.522-3.731l.985-1.736a33.641 33.641 0 0 0 8.987 3.519zm-378.745-4.673-1.073-1.686a33.95 33.95 0 0 0 7.317-6.302l1.5 1.314a36.072 36.072 0 0 1 -7.745 6.673zm361.147-5.331a35.941 35.941 0 0 1 -5.99-8.292l1.765-.929a33.98 33.98 0 0 0 5.659 7.833zm-347.837-9.934-1.811-.837a33.663 33.663 0 0 0 2.737-9.265l1.975.286a35.635 35.635 0 0 1 -2.901 9.816zm338.45-8.013c-.064-.33-.126-.659-.182-.993h-7.3v-2h9.017l.122.857c.082.587.181 1.166.3 1.742zm-17.45-.993h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.963zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.975v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.98v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.968zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973zm-19.945 0h-9.973v-2h9.973z" transform="translate(-237.397 -72.746)"/>
        <text font-family="Poppins-Medium, Poppins" font-size="28" font-weight="500" letter-spacing=".05em" transform="translate(78 70.476)">
            <tspan x="0" y="0">This is</tspan>
        </text>
        <text font-family="Poppins-Bold, Poppins" font-size="112" font-weight="700" transform="translate(79 172.476)">
            <tspan x="0" y="0">a test</tspan>
        </text>
    </g>
</svg>

Note that in this case, you MUST import your fonts!

<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">

Hope this helps someone out there!

Good luck 😊

1
  • It's not clear how this is better than the accepted answer; it seems more verbose, and AFAIK using a base64 encoding on fonts doesn't restrict you to using SVGs inline. Can you explain the cases in which this solution is better? (n.b. I'm not saying this is a bad answer, just asking for more context).
    – Jules
    Commented Aug 17, 2020 at 17:36
-1

Ran into the same issue and made a tool similar to nano and svg-buddy. Compared to nano it's a free tool. And compared to svg-buddy it's written in NodeJS instead of Java, so it's easy to install (or contribute too!) for anyone who already has Node on their computer.

The tool is optimized for Google Fonts. It infers which letters are used by scanning the SVG for font definitions. The letters are then passed to Google Fonts so the most optimized font files can be returned. This optimization results in a dramatically smaller file size.

https://github.com/coolov/svgum

1
  • 1
    Great! Mind editing your answer to explain what's different or better in your tool? Why would someone choose your tool over the existing ones?
    – Luciano
    Commented Aug 4, 2020 at 12:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.