26

I'm embedding SVGs in my page with the <object> tag, and they're supposed to utilize Google Fonts (e.g. Roboto). However, the SVGs aren't picking these fonts up and instead default to system fonts.

What am I doing wrong? Does every SVG require that the font itself be embedded in <style>?

Example code:

<head>
    <link href='https://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic' rel='stylesheet' type='text/css'>
</head>

<body>
    <object width="250" height="200" type="image/svg+xml" data="img/popup_image.svg"></object>
</body>

SVG snippet:

<text font-size="14" fill="#333" font-family="Roboto">Words go here</text>
daveycroqet
  • 2,667
  • 7
  • 35
  • 61

3 Answers3

38

The browser treats SVG text as regular HTML text. In other words, any text elements in your SVG must be styled like normal HTML elements (like a <span>, for example). You need to embed your font in your SVG in the form of a CSS @import. Look through the XML of your SVG for the <defs> section. Then, add this code to it:

<defs>
  <style type="text/css">
    @import url('https://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic');
 </style>
</defs>

Next, update your <text> element to be like this:

<text font-size="14" fill="#333" style="font-family: 'Roboto';">
   Words go here
</text>

If you want more information about this, you might try this website: http://nimbupani.com/about-fonts-in-svg.html. It has some pretty good information on fonts in embedded SVGs. A working example of this can be found here: https://github.com/marians/test-webfonts-in-svg.

  • Appreciate the effort, but unfortunately this did not work as I'd hoped. – daveycroqet Mar 28 '16 at 01:34
  • Looks like you were close! Doing `@import url:()` seems to be working... still testing though. – daveycroqet Mar 28 '16 at 19:15
  • If you get it working, let me know so I can edit my answer so it can be useful to others :-) –  Mar 29 '16 at 05:15
  • 2
    No `CDATA` required. Just use: `@import url('https://fonts.googleapis.com/css?family=Sonsie+One');`. A working example comparison can be found here: https://github.com/marians/test-webfonts-in-svg – daveycroqet Mar 29 '16 at 19:50
  • 1
    Doesn't seem to work anymore, checked your example on github. – Stafie Anatolie Apr 02 '18 at 13:17
  • 2
    This is good solutions and its working, but font is not working when i take svg file in html. have you any solution ? – chintan Aug 03 '18 at 13:53
  • 2
    Google Fonts appends a '&display=swap' to the suggested css import statement. Firefox complains about this and refuses to render. It suffices to simply remove this suffix to make it work/render again. – Ideogram May 22 '20 at 12:10
  • @Ideogram apparently some modern browser complain about the suffix `display:swap`, so removing it successful rendered the font. However, does anyone know what this suffix does specifically? – KareemJ May 14 '23 at 13:05
16

Some suggestions if you want to make your logo portable and available offline you should consume and embed the smallest version of your font possible.

First, optimize the font size, by only pulling in the stroke weights and characters you actually need.

So instead of this:

https://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic

Condense the options and also add the ?text=abc param to only grab a subset of glyphs like this:

https://fonts.googleapis.com/css?family=Roboto:700&text=Words%20go%20here

Inside your svg, you can include a @font-face declaration in a stylesheet in the <defs> tag like this:

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

Grab the file by navigating to the google fonts stylesheet and downloading the actual .woff2 file. You can convert it to a b64 string using base64-encoder or read more at Converting and rendering web fonts to base64. Take that string and include it in your file. Just for clarity, you could also specify the unicode range on the font-face to make explicit that you're only pulling in some characters

<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink" 
     viewBox="0 0 280 140" width="300">

  <defs>

    <style>
      /* https://fonts.googleapis.com/css?family=Patrick+Hand&text=KAM */
      @font-face {
        font-family: 'Patrick Hand';
        /* src: url(https://fonts.gstatic.com/l/font?kit=LDI1apSQOAYtSuYWp8ZhfYeMXNDN0vF8&skey=7fb0ea6515a61339&v=v11) format('woff2') */
        src: url(data:application/font-woff;charset=utf-8;base64,d09GMgABAAAAAAo8ABEAAAAAErgAAAngAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbIBwwBmAARAg4CZMREQgKhUyFHQsKAAE2AiQDEAQgBYUoByAMgRAbWRFRVJN+SKaRsnD+fv7/50zfF9g8MwFU4Cl/5EylLwfI7XFIsscnDc2wVPwK87KAKsFm2yuHd1mWdu1uHfvw32l/7p2ZQqGmSR2VSAFknaawNtkHeh6MtA9f0q/gP+33rc7MmsdtKhAi1LZ7vs6962Yh4l30PdQaiaVtSbAJ8ZA7EDE2vUUWFoLxq6I3CSJqUKPIIFFlc/pkohptoi0ketMnFqhC1sm80SiQtRWuqE3mya2+eOf8VdpyLbt3g7Z0MXiEKf4QP5JNZORGQl7q8Xk38QHtFqtPLrLLi8tRYtLi8eVTdOTO21Za9PpPImul6LBHvxAs/jN+K2Ey080059VpB0EW7dSVMo63HKXjdLJsW/YYvRo9Hz0LNotB8UlabkL/HYy/xb+j0es/rZXkGL9vu///aiAF1hdCCMXnGK9mYLXe4Q377yaudJ08YczMJC6OpA6jswzspGm3ej87h6nNZIoZOyu0UylePZEvcJ5njNpMoh0GN6lWVvvF/jvrNE0dUJCmEsRxnE/TEIbiPsPysnMMO55JYMsIJRk5rptC6BCmkq50+Vxhn4n4aOdhXRi+yxxBzDnnoKDYaXv5bKJnnGwuTWTqMo7MJ6DASbktmVcLYSmU42BIBsU6CmErlL27SAbJKMNHZ+rDYPkhSopTM9Lon4Xon9E9C1LLB4wpkEXF8jT3c5kVmCV/2eRI0AF2cCRXvWB6MuuFfNOKKmy7D5H1QlQVhGZGNX7b1zBGVUYpaltyTtaGh6gpfmHRmckrnM1lhnqsOdeMuoxkyDur4wtJURa9dBLN8/JRiIY6Ppscnz+Q5bhNl1Uxm6qgRrz4Ro1GDJFFqAUpKIbhRUW1LGuPhlgrGaY3kxSCYg2L4jznJPtXfVdCZOtURwX/OYa392kpqvEAtXig8dGZ4npqQbRK9iBi0KGhEKKoj2dMFWT3FxJCQ0asIbKnzaagOkVRroumHeB64GxLQ4yrgsaCEBOqEHOxQhlipTLFKmWJ1coWa1RJrFVlsU5VxHpVvRIbFCqBWblRbpAO0JsAejNAbwHorQDNAO0C9DaAloCaScXd82/sKdZoao4lhC58nZX+ECZ9N0RLwQvg+SG2K+YBS3iNMutIzheTAwMcNw0xJWWIWIvtfs6anfYveSOr0xyu8RXvS0lmoEg1dZWDgnixKqG1T54nX9Y7JDuFL9b4IZTiLg8S/16gOOuECFV7XTdEW/EGEPHZTogdqjBorcdtHjxeT4LhHcvzgRzIjJMzzoP9ljIatoVYs9oPsVOB1sLyYHmnk/mCfnA+b0vmbt4JsetUDrfrxQzrKdHcDxj6EXrikdnkscEmO4+NlrkxjR7qlkrMuQxoIKc1rBgfndF3sPUZdQcj1uckzDg7x3AYcebAjPVd+x746EwmmWG15HTWcSQq8TQMD5VYT57mCkmaJaxYF1uz7WWwoxXDaqWMPc1enj7HdaSbaqtOQ+zOSyJmht3qIbudEHsOnYaKjJh5GrpR0Lw368JMM4QZTgtJm7vSddJkO0CctKPoWj3Y3rGrrLR/Voptu3lsgpK8htL2GUuPi5T056AcH50RvXm/ktzO+sum5xLupu2iJVYHIQ4cOmtmmU7AmdUXf1NhZxDj8LcUdgU5c/ey7pR3Sg/BD9lShxBntQt5V4O98HAb9LXw+bzDkh1Xdr7tSb3eJTfNOlZeKbAQj+m5+ZZsXfRZy4t2p4IKsmvPoSrMi7ZUbSl1ZEoWpSoeluyHcGfcEJlDsCXZBdexNyq2PQgilwn2JLtQYhOcSXahVJbx5RbewVf4LB4hsstst9QdhVKrXSi3PQTkW73mCttDIAtRyWRPV2GBqtWyQNWgRLUAqgNQPTJHNQBqBFATgJqReaoFUCuA2gDUjixUHYA6AdQFIDcyVx0DdBxAJwANJ21CahHTqY0sIbPhclpm8ZkbJqUvs4UnIy0gdWOBvT3APaAnej3Sqa9vgft7gAcAYtAjg4b6Fni4B3gEYDRqswohvQIT07Tweib7t2vN//9D9PJldpoWstRr5dTbm9jOJ+VfvP/j9BFW67D/2faA+7KNO313X28+VF5+6JPf2nalj2x+0XnU7vsEG4rLAv4rNg87Nz83bz4Q7tcE2o+OOq8J99+FjU/aAu2X3ae4b+NO3+FhywcJN22oPwnzmeb9hsDWjXeG+QjZPCQvfOIruXGjfeOJMB85IszmPf67NIGA/+3nnQ933kAv1ui0ZYU35x1nRLxlYu5O1drMY3siW5rJ+FVqmaFq8DJzsbXNPiaqFhScZH40PCZdl/FCXtVkvXTsjPIDmXpV5GWedrd0z2Ye/8skdkXwE9cWVre25o2uXjXMO0bMGV09N6/OPuJs13Aup0HK4yp1N3vzZl6nQct/lcVMizTjNb4f9HfguCZIoYuG+2W9ZNx0IZixouGuX3bNN6mrfv4JAFzZ4FjKcnQAlLCU9AUTlkVrEAEiShlCiJiUGfQEMRZ9vCFeqZCIQ0OgI7oQkdVlsEQrwhiOgpQQAshLGUJpJC1LNMTHsjJrrRDa1OUKj6SUYyWEcrREVyuIm7pc4ZGUcpAQytESnSs8klLuZLXbXSuEMNGCAyUcPR6kswIsa8k4Xa0Q0dTlUioPs0HUzlSd9mkUZ8rXYtM8U8uPtHZzu91ul1SGp5mMaqVYFBKEJJIULLK6HE8ieEWxo1WeFuX/GhLO/ODVvpt7709zkwc++PfL/95grmSlV286dbngbpwwwLz/75f/7TBXui6BLL4xJT9ATcPhpK1IU5axOOVSdaWIQxrGmmW3hV4UvDgEfQ5TFhta5z0XCusiAnXdSiRFFK6PZJCPexez6kiOAD/UByGO8OGikE6jUIpxTGARUxhEPwYwAx4J8CIRPFKRjBSk1lqa4MFMqciL4drjO+FBP3oxjSn0YhAzZZ6K9Lmj8GAQI3BhIvjK8zV2qJdP1C2rmsbQg5ZS137MYgQe/q0UOJCMZKQhD+2oRScakBfNXlvODneYuvo0BjGOMfB6WprQCn5rypGeAxjHDLxBM+bqTQ5kIbmOPJYMo1fd1AcHRijqRiqcMTbPRhpSkYM88Jjh/h7MYgbjGMAgxiTmOW0tOUiHQ2htr7d4kYV06XvaMQIe2UsIW5KB5G5a5WWxdnkhXZzekfMjzehHJcpg3mPvdD36BOKBdJpNIBdOODENb+CeE5jBNBzCPX0EDoxjCv1wohEVqHPsU5oX+/9RpGJgWPsE3mjpepCQ8908vPzjP4KzDCF7MOUtrOszH39BY7PHUZp/J8FeB1OpvvBH4Piu+9hnYMjesC5K/rBRKvnD1aWSnw6tqWp/rjdsVMp+UTJ7xaT4ajbBka+SLdUqfWFRFY+50Qsx+hzWd4VNPQAAAA==) format('woff2');
        unicode-range: U+004B, U+0041, U+004D
      }
      text { 
        font-size: 140px;
        font-family: 'Patrick Hand', cursive;
        font-weight: 700; 
      }
    </style>
  </defs> 

    <text x="51"  y="132" rotate="-30">K</text>
    <text x="100" y="100" rotate="0">A</text>
    <text x="150" y="95"  rotate="30">M</text>

</svg>

See Also:

KyleMit
  • 30,350
  • 66
  • 462
  • 664
  • The font is still not displayed correctly in Ie or edge. It defaults a different font in those browsers. Is there a fix for that? – theyuv Oct 22 '19 at 08:00
  • @theyuv, the above snippet only inlines the font file for *woff2*, which is not supported by IE11. You could add fallback support for [other font formats](https://stackoverflow.com/a/40533065/1366033) for legacy compatibility – KyleMit Oct 22 '19 at 19:18
1

Kyle's answer is awesome, but didn't quite work for me, but it lead me to the right answer:

You can define the font as local if you already have it on the page

@font-face {
  font-family: 'Bitter';
  src: local('Bitter');
}

I'm making a website where I'm already using certain fonts and couldn't get them to load, but ideally I wouldn't even have to anyway since they're already loaded. This solution worked perfectly for me.

Justin
  • 945
  • 12
  • 26