Grow your CSS skills. Land your dream job.

SVG `text` and Small, Scalable, Accessible Typographic Designs

Published by Chris Coyier

Let's say you designed something with custom fonts that was a little bit fancy. Perhaps a certain word is positioned between the ascenders of another word below it. Some text is kerned out below to match the width of that same word.

This is something we might tell a graphic designer switching from print to web to avoid. It's too finicky. Too much touchy, unscalable absolute positioning. Too much risk from different font rendering behavior.

But with inline SVG, we can do it, and do it well.

SVG <text>

The big "trick" here is that SVG has a <text> element that is just that: text. Not outlines of text, just regular ol' selectable, accessible web text.

<svg xmlns="http://www.w3.org/2000/svg"
     width="800px" height="300px" viewBox="0 0 800 300">

  <text x="25" y="55" 
        font-family="'Lucida Grande', sans-serif" 
        font-size="32">

    Regular ol' text here. Hi.

  </text>

</svg>

See.

<text> is happy to use custom fonts

Using @font-face and custom fonts on your site? No problem. That SVG is happy to use them. This works with inline SVG, where you can set font-family with CSS:

<text class="hook">Some Cool Text Yeah.</text>
.hook {
  font-family: "proxima-nova", sans-serif;
}

but it even works for SVG-as-<img> (or background-image, presumably) as well, as long as the font-family references the custom font by the right name.

<text x="25" y="55" 
        font-family="'proxima-nova', sans-serif" 
        font-size="32">

Use Design Software

I haven't tested a ton of different software, but Adobe Illustrator can "Save As" SVG. When you design with text elements, <text> is what you get in the .svg file.

You might have to do a little hand-tweaking to remove or adjust the font attributes/styles.

The beauty of this is that it takes away finicky task of positioning with CSS and lets you do it right in software that is awesome at it. Then the actual positioning happens with that matrix transform.

Scales Perfectly

If you were trying to replicate a design like this in just HTML/CSS, it's not just that the positioning would be finnicky, it's that it doesn't scale. Something like font-size: 41px; top: 37px; left: 81px; works only at one size. Perhaps you could do something with vw units and percentages and stuff, but it's just a lot easier in SVG.

In SVG, the font-size you set is relative to the size of the SVG itself, not the whole document. So if you adjust the size of the SVG (it can easily be fluid width), your typographic design stays perfectly intact.

A fluid width kinda setup:

<div class="ad-wrapper">
  <svg class="ad">
    <text ... />
    <text ... />
    <text ... />
  </svg>
</div>
/*div*/.ad-wrapper {
  height: 0;
  padding-top: 100%;
  position: relative;
}
/*svg*/.ad {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
}
Scales proportionately. Text is still selectable as normal.

Design with fonts you have on the web

This workflow works best if you can fart around in local software with the fonts that you also have available via @font-face. For instance, if you were working in Open Sans, you could download a copy of that for desktop use from Font Squirrel but then use it on the web via Google Fonts.

I think Typekit makes this workflow pretty nice, with their desktop syncing feature. When you're picking out fonts, you can add them to a Kit to use on the web, as well as sync locally via the Creative Cloud thingy.

Then they are available right in Illustrator.

It's a little funky because the font-family names will be a little off. For instance, you might get like

<text font-family="'MarketOT'">Example</text>

from Illustrator, but on the web it'll need to be like

<text font-family="ff-market-web, cursive">Example</text>

But hey that's just part of the job. Maybe there is a good reason for it. Maybe someday they can get those things in sync.

When to use

If you're using the same custom fonts elsewhere on the site, it's a no-brainer, go ahead and use <text> based designs as needed. If the fonts in use aren't used elsewhere, it might be a tall order to include an entire custom font just for use in a single graphic. Or perhaps not. You'll have to balance the options yourself.

In the example I've used here, I used Proxima Nova and FF Market from Typekit, and the Kit was about 115K. Not too bad if the rest of the site was using those fonts too. But then I converted the example to outlines (meaning <text> is out and <path>s are used instead to draw the letter shapes), and the file ballooned from an incredibly tiny 4K to an incredibly large 260K (bigger than the entire fonts, albeit unzipped).

I'm sure in some cases outlining makes good sense, and sometimes even a retina raster graphic works, assuming you take all the necessary accessibility steps (a good alt tag at a minimum).

Demo

Here's a demo that shows everything at work, including the scaling, selectability, and the custom fonts at work:

See the Pen SVG with example by Chris Coyier (@chriscoyier) on CodePen.


Wanna learn more about SVG?

I have a full course available called Everything You Need to Know about SVG that covers the whole spectrum of SVG from the perspective of a web designer and front end developer.

Comments

  1. I use an inline SVG as my logo along with the site name converted to outlines. Is there any special support stuff we need to consider? Or can we just go along and replace the outline with SVG text?

  2. Wow! Great post on something vitally important I’d overlooked. I’d always outlined, because when I opened an .svg from my desktop in a browser, text was in the browser’s default font.

    This could really reduce file size for graphics with a great deal of text. Thought experiment: Imagine a low opacity background graphic meant to represent computer code, newspaper print, handwriting, etc. As outlined text, an .svg could be huge, but as text, it would be a manageable size.

    It also makes editing an .svg graphic much easier (think of a graphic promoting a recurring event – it’s easy to just go into the .svg and change the dates).

    Does anyone know if** inline .svg text has SEO implications**? Do search algorithms treat it as text-text (regular content), or ignore it like they would ignore outlined text?

    Thanks!

  3. JCD

    I’ve notice almost none of your inline SVG examples work in Firefox (the SVG part doesn’t show at all), which is weird since it’s supposed to support it fully.

    I played around abit with your Pen, and noticed that the SVG part shows up if you remove the div’s surrounding it. Does anyone know why this is?

    • I heard someone on Twitter say this, and turns out it was because the div had a class name of “ad” on it and ad-blockers prevent it from showing.

      Which kinda makes me want to put <html class="ad"> on every single one of my sites.

    • Nico

      Ya, Adblock is pretty dumb. I once struggled for months to understand why my custom font face didn’t show on my site. The issue : Adblock blocked it because it was named “Reklame”… Damn !

    • Reklame ≈ Reclame from the verb “Reclamar” in Spanish.

      Reclamar means “to Claim”. “Claim” can certainly be associated with ads in more ways than not.

      I actually think AdBlocker is pretty smart, admittedly, too smart sometimes.

    • Nimi

      Does anybody have info on how to achieve this with inkscape? After a quick test it seems that inkscape saves text elements inside tags

    • JCD

      Hah, of course it’d be something stupid like that.

      (Some sites put up friendly reminders that their ads aren’t intrusive and ask users to whitelist it in Adblock, which might be an idea. With the web being as it is, there’s no way in hell I’ll uninstall Adblock completely, and I’m sure many feel the same)

    • Werner

      Reklame is actually german for Ad.

    • luci
      Permalink to comment#

      html class="ad" seems to do nothing (via Firebug).

  4. Travis

    FYI – Google Fonts also allows you to download local copies so if that’s your web-font vendor of choice you don’t need to go anywhere else to get your local design copies. Also if using one-off fonts is a problem Google has a beta feature that lets you pare down the list to just a few Glyphs – https://developers.google.com/fonts/docs/getting_started#Optimizing_Requests.

  5. Really great.
    Does anybody have info on how to achieve this with inkscape? After a quick test it seems that inkscape saves text elements inside tags..

    • Jimmy

      By saves text elements inside tags you must be refering to the <tspan>. Inkscape expects all text objects to be wrapped by this tag, mainly for multiple line text, SVG does not require this for single-line or single-format text elements.

      To produce something similar to Chris’s example you have to maintain the x and y values produced by Inkscape in the <tspan> tag, or the text will just disapear(need to dig into this). Another thing with <tspan> is it will not scale proportionately acording to it’s parent div (in this example .col).

      For scalability i copied these xy values into the <text> tag and deleted the <tspan> wrapping the text, added a class to it and copied the styles to my stylesheet under that classname and it works!

      The Html

      <div class="col">
          <div class="ad">
              <svg width="740" height="400" viewBox="0 0 740 200">
                  <g transform="translate(0,-852.36218)">
                  <text class="logo-title" x="46.933014" y="984.6662">SYNDICATEFX</text>
                  </g>
              </svg>
          </div>
      </div>
      

      The CSS

      .col {
        width:30%;
        margin: 0 auto;
        -webkit-transition: 0.4s;
        transition: 0.4s;
      }
      .ad {
        height: 0;
        position: relative;
        padding-top: 81.75%;
      }
      .ad > svg {
        position:absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
      }
      .text{
        font-size:96px;
        font-family:'Bariol-Regular',sans-serif;
        font-style:normal;
        font-weight:400;
        line-height:160.00000238%;
        letter-spacing:9.20999908px;
        fill:#000;
      }
      
    • Amelia BR

      @Jimmy

      If only it was that easy. I just tested it out, and Inkscape uses custom elements for text in order to allow for automatic text wrapping. Even when you use the “Save as…” “Plain SVG” option, you still get all these elements that are not part of the standard SVG specs (they were an experimental spec which was abandoned) and which are not rendered by the browsers.

      For @hannenz and everyone else who has this problem, here is the solution to convert your Inkscape flowed text into standard SVG text elements:

      Select each text block, and then use “Convert to Text” under the “Text” menu to lock in the positioning as plain SVG <text> and <tspan> elements.
      Save the file as a “Plain SVG”
      Open the file in a text editor, and delete all the extra Inkscape cruft (everything between <flowRoot> and </flowRoot>).

      The Inkscape manual has more on the different types of text elements and how to create them (so you can skip creating the flowed elements if you’re only using absolutely positioned single-line chunks of text anyway).

  6. James Deering

    You are just now finding out about this? SVG has been a W3C standard for over a decade, why haven’t you been working with SVG before now?

    You do realize that you have wasted over a decade of your work life by not wanting to study and learn (much too hard). Your dependence on others to dictate what you will do and when is not very admirable.

    • Hey James. How ya feeling today buddy? Make sure to get enough sleep!

    • Maciej

      James, nobody is claiming that Chris is an expert in this field, nor that he knows everything about front-end. He is very good at writing about CSS, HTML and front-end development, and that is what makes his blog popular, even when he’s only learning and discovering old things now.

    • “SVG has been a W3C standard for over a decade”

      But, the lack of IE8 support and understanding of .svg among the web development community and availability of .svg stock art have limited its’ use up until now. The point of the blog post is help with understanding about .svg and encourage adoption. A meaningful portion of web images on new sites being created right now are too big and too low resolution because they are .jpg or .png. While I applaud you, James, for immediately adopting and understanding all W3C standards, the rest of us mortals sometimes need to catch up.

    • Gabe

      Looks like James was hittin’ the Haterade™ pretty hard this morning.

    • Aaron Staker

      Besides the issues with .svg having issues in a variety of browsers out of the box it’s not easy to create .svg artwork it requires a fundamental understanding of Illustrator, Inkscape or equivalent which is vastly different from photoshop or pretty much any of the standard bitmap programs out there.

    • Mike Morkes
      Permalink to comment#

      Considering SVG wasn’t rolled into IE until version 9 (that’s not even counting those who didn’t upgrade IE 8 even when IE hit version 10), what was the incentive for developers to use a W3C standard that 80%+ couldn’t see without downloading a plug-in? (good luck getting your average internet viewer to be able to download and install a browser plug-in.) IE 9, which finally supported SVG, didn’t come out until 2011…so what would have been the point in working with SVG, beyond dabbling and maybe bragging rights?

      Your snarky comment offers nothing to the discussion. We’re here to learn (better late than never). Please respect that or find somewhere else to spread your negativity.

  7. Jeff Rubow

    Typographic nitpick:

    From the opening paragraph of your article:

    Some text is kerned out below to match the width of that same word.

    Text is not “kerned out”. Text is spaced out. Kerning is a very specific kind of spacing that only applies to a pair of letters where the natural spacing would look wrong. For example, between a capital A and a capital V. Sometimes the characteristics of a pair of letters together make the space between them look like it is too much or too little. Kerning is done to correct optical problems between two specific letters.

    But that is not the same as spacing out all of the letters in a word or phrase. That’s just spacing.

    Programmers get this wrong a lot. In fact, I’m currently working on a project that uses imagemagick. It has a function for letter spacing. But it calls it kerning. CSS actually did this right with the “letter-spacing” property.

  8. Does anybody know if Google indexes the text inside of the .svg elements?

  9. Osmos

    Can we polyfill this awesome feature for browser that don’t support fully SVG or not at all support it?

    • Chris has another article on exactly that: http://css-tricks.com/using-svg/

      But it looks like SVG is so well supported these days that polyfills might not be worth your time.

    • IE8 doesn’t support .svg, and, painfully, it’s still at about 10% market share. There are lots (dozens) of solutions to provide fallback. It’s not that time-consuming to save an image as .png and .svg (always use .png instead of .jpg in the event the images are transparent), and put them in the same place on the server.

  10. Hi everyone,
    This perfect features but, if installed AdBlock or other adv. blocker on browser, does not work.
    Thank you for article Chris.

  11. Pete

    but it even works for SVG-as- (or background-image, presumably) as well, as long as the font-family references the custom font by the right name.

    In my experience SVG-as- has some major cross-browser issues (try in Firefox) with linked resources due to security concerns.

  12. Looks like you accidentally a word in the first sentence after “Scales Perfectly.” Handy article nonetheless!

  13. Chris

    Somehow the demo does fail in Firefox (newest 29.0.1/Win) but works in Chrome and IE. the space out text is actually not. Any idea why?

    • Amelia BR

      Firefox doesn’t yet support the letter-spacing CSS property, nor some of the other typographic CSS properties.

      To get the spacing to work in Firefox, you need to use the dx attribute to add the adjustment. It’s a little messy, however, since you have to give a list of adjustments for each individual character:

      <tspan x="41.5005" y="141.4561" fill="#0093C0" class="sans on" font-size="14.5332" dx=”0 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10">BLUEGRASS FESTIVAL</tspan>
      

      P.S. To Chris: I see you implemented the automatic credit line in forked pens: nice! Less nice: block code doesn’t seem to be getting encoded properly in the comment preview.

  14. Thank you for article Chris. SVG is great, it has some disadvantages, but nevertheless it is often a great help.

  15. Gabe

    I’m digging how this could possibly help reduce file size for things like textual logos.

    I recently gave up on SVG and went with a scaled PNG for a logo, because the SVG was over 60k and the PNG was less than 30k. I know the big SVG file size was from the text paths.

    I’m glad you also pointed out that unless you’re using the custom font elsewhere, the file size savings could be negligible. But what if the custom font was heavily subsetted so that it only contained the characters used in the logo? BRB, gonna go try that…

    Just when I think SVG can’t get more awesome, I find out another awesome thing.

    • Jozef Remen

      Saving SVGs with only 1 decimal space as well as “simplify paths” in Illustrator can make things smaller. Also, using Symbols for parts of SVG with same appearance reduce the amount of data. And of course, if you have some parts of the image “cut out” with the Pathfinder in AI, it’s ALWAYS needed to cut off those paths with a knife tool in AI, as the paths are still there, just not visible.

      Anyway, all of this will not help you to reduce the size of SVG if you are using drop shadows (bad, bad, bad! – it’s prerendered as bitmap in data uri) and outline the text. This should really be avoided if you don’t have a strong reason for doing so.

  16. Lewis

    This is a great post and perfect timing for me at the moment. I have a question, does anyone know if these SVG’s are seen by search engines? I want to use an SVG as a product title on a product page at the top, in normal cases I would use an H1 but would love to maintain a nice typographic design I have for each product AND still be good for SEO. Maybe I’m asking too much :-) Any help is much appreciated.

    • Ben Smith

      This article states that they indeed do index svgs.

      http://googlewebmastercentral.blogspot.ca/2010/08/google-now-indexes-svg.html

      However, I’ve been digging around and I didn’t find anything in regards of using H1s, H2s, etc in SVGs. I’m guessing it’s not supported. I’m guessing the best you can do is wrap your code in a H1, but that’s only good if you don’t have more than 2 “types” of text. (IE: if your SVG would ideally contain the H1 and the H2)

      Anyone have some further knowledge in that regard? Can you put anything else than inside SVGs effectively?

    • Just an idea off the top of my head, not tested:

      Keep the h1 tag on top of the SVG (yes, you’ll need to type the same text twice, but that’s very minor overhead, if any) and then do the well know image replacement technique on it:

      .hide-text {
         text-indent: 100%;
         white-space: nowrap;
         overflow: hidden;
      }
      

      I would add margin:0; and height:0; for good measure.

      That you get the best of both worlds: Nice scalable and responsive text with SVG, plus the SEO “compliance” with the h1 (or any heading for that matter).

      http://www.zeldman.com/2012/03/01/replacing-the-9999px-hack-new-image-replacement/

    • Amelia BR

      I would usually recommend that you put the SVG inside the heading tags.

      Fancy Heading

      Old browsers like IE8 that don’t recognize SVG should still give you the basic heading styles, search engines and screen readers should recognize the SVG content as being part of a heading, and you’re not repeating elements so there’s no risk of editing one heading but forgetting to change the invisible heading text to match.

      On Ben Smith’s comment regarding multiple heading levels represented in a single image, I think in many cases you could break it into two (possibly overlapping) SVGs, but if that doesn’t work for you, you could use the ARIA “heading” role to specify the structural level for each text or tspan element.

  17. For a “best of both worlds” approach for heavily stylized text (not just a font), or in lieu of including a font just for one SVG, such as a logo:

    Convert any special font text to outlines
    Include the text inside of a text fill="transparent" element positioned over the outlined text
    Users can now select text out of the SVG without the need for special fonts!

    No idea if this would be considered a “black hat” SEO technique, though.

    • I think that would be “black hat.” Too much like the old black-hat tactic from the late 1990s of including lots of keywords as small white text on a white background. I’d go with the theory that Google will ultimately (if they don’t already) be able to read text inside an .svg. They do understand the alt tag, and I’d think their brilliant algorithm could figure out that there’s no meaningful difference between a picture of a pizza restuarant at the top of the page and text that says “pizza restuarant.”

  18. The main reason I can’t switch to SVG in my current project is that SVG’s fill color can’t be manipulated by CSS when inserted via a pseudo-selector.

    Example:

    a:before { content:"\2022"; }
    a:hover:before { color:#f00; }
    

    As far as I’ve been able to find, this is not possible with SVG. Am I wrong?

  19. Mike Palmer

    What on earth is a Mouutaiu?

  20. Does anybody have info on how to achieve this with inkscape? After a quick test it seems that inkscape saves text elements inside tags..

  21. Great writeup Chris!

    I’ve used the text element in SVG for responsive chart labels, and the resizing works like a charm. The only downside is that if you want the text inside a bounding box, you have to stick another element (such as a rect) below it, and size that to the width of the text.

    It makes sense though, this is what you’d do in illustrator anyway.

  22. Martijn

    The demo only shows the two checkboxes and nothing else…

    • Most likely: you’re using an ad blocker. And that ad blocker is blocking div’s with the class of “ad”.

      I’d change it, but I think it’s a funny lesson.

    • Martijn

      I think adblockers are not that simple anymore these days.

    • Martijn

      …As proven by this fiddle:

      http://jsfiddle.net/3qtsQ/

      The text shouldn’t show up if I follow your logic, but it does. So something else must be going on.

    • I think it’s pretty much that simple, except that it’s site-dependant. There is an actual ad on CodePen that uses the class name “ad”. So someone went out of their way to report that to some global repository of things-to-block, and thus it’s blocked on CodePen.

      I’m not bitter about it, I’m just not going to change a demo to please people that block ads on my site.

    • Martijn

      Of course you aren’t. But at least you now know that it’s a thing.

      And that class=ad is not a great idea in any project regardless. So I learned something extra today.

  23. I dont see anything. Chrome Version 34.0.1847.116 Ubuntu

  24. Ben
    Permalink to comment#

    I’m late to the svg party and finding them problematic across webkit in responsive builds I guess across website … can’t seem to control vertical size/spacing of svg element. I’ve found is support generally lacking also – is there a particular process here I’m missing? (…at the moment I pretty much use the svg embed code pasted straight out of illustrator)

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".