I'm trying to add some text to a SVG file. The text is dynamic and shown over a rectangle which acts as background.

Since the text is dynamic, the width of background rectangle also needs to be dynamic. So, to be consistent, I'm using a fixed-width monospace font (Droid Sans Mono) and calculating the width of the background rectangle by using the expression - (x*6.4)+4), where x is the number of characters in the text, and 4 is added for padding (2 left, 2 right). Also, assuming that 6.4 is the avergae width of each character in the Droid Sans Mono font (just a guess).

So, for text Ruby on Rails, number of characters are 13, so the width of the background rectangle is 13*6.4+4 = 87.2.

Which works perfectly in browsers (Firefox and Chromium) on Ubuntu. However, when seen in the same browsers (Firefox and Chrome) on Windows, the text overflows the rectangle.

So my question is that, how can I ensure that the image has consistent look across different operating-systems? The image does has consistent look in all browsers on same operating-system.

I'm including an example image for reference:

SVG image as reference


Maybe I should rephrase my question - Inside an SVG file, how can I make a fixed-width font take same number of pixels across all platforms, assuming the SVG file is not affected by any external CSS styles and the zoom level is normal?

Also, I understand that alternative technologies exists (PNG etc.), but not every SVG question should end with replace it with PNG. Also more than a solution, I'm interested in understanding why this problem exists with SVG. I am using a fixed-width font which is supposed to take same number of pixels on all operating-systems (Is this wrong assumption? Why? What can I do about it?).


Ubuntu 12.04 amd64 / Firefox 13

Screenshot from Firefox / Ubuntu

Ubuntu 12.04 amd64 / Chromium 18

Screenshot from Chromium / Ubuntu

Windows 7 32-bit (inside VirtualBox) / Google Chrome 18

Screenshot from Google Chrome / Windows

Windows 7 32-bit (inside VirtualBox) / Firefox 13

Screenshot from Firefox / Windows

  • 2
    First of all, I would most likely do this something like this jsfiddle.net/lollero/6tuSH Second of all, this seems more like stackoverflow question to me. Third of all, if you use image, you can either use few images to repeat the parts that need to be flexible, or make it wide enough to leave some room to grow and hope for the best.. ( though I would use .png's ) – Joonas Jun 20 '12 at 12:35
  • 1
    @Lollero: the problem here is that he is calculating the size, and it isn't working. This will happen regardless of the method used to create flexible part of the image. – horatio Jun 20 '12 at 14:49
  • @horatio I didn't say that flexibility would fix any size differences of the font (zooming also may create some problems with this svg setup in some browsers), but it can fix the problem that comes from that, which is text busting out the colored areas. More so in my jsfiddle example since it is flexible both horizontally and vertically. – Joonas Jun 20 '12 at 15:21
  • ..and I also like to have flexibility where it counts. I don't really know the use case for this, but what if there is suddenly 200 votes? The text wouldn't fit inside the green colored area, but if that would be flexible, it would fit like a glove no matter how many votes you'd have. That would probably be the most practical example of why this current attempt would perhaps fail (depending on the use case of this of course). – Joonas Jun 20 '12 at 15:37
  • As I got home, I noticed that my example didn't work in firefox and.. that bugged the crap out of me, even though it's just an example. Here's jsfiddle.net/lollero/6tuSH/3 ( noticed that in this fiddle, I did some things quite strangely, but.. I'll just walk away now.. :D ) – Joonas Jun 20 '12 at 15:48

Since you have only linked the SVG and not provided a screen capture to show what your problem is, I can only go by what I see. The image as shown in the question renders improperly because it is not the proper typeface, so your rendering is off because your calculation is predicated on a different letter size and spacing (I see Courier). If I view the SVG in a new tab (or follow the link for the the direct link), it renders properly with Droid Sans Mono and the proper rectangle sizing.

So basically, your problem is a CSS problem where the typeface is being cleared by a parent container or improper calling method. In this respect, I would agree with Lollero that it is off topic for GD.

One way to handle this is to store the font file on your server and render it using PHP GD calls (pretty trivial). You can store the result with a checksum etc so that it will rerender the image only if the text changes and use the stored copy otherwise.


A screen capture of your svg file on win7 64bit firefox:

Screen capture

The plain-text contents of your SVG file (XML)

<svg version="1.1" baseProfile="basic" xmlns="http://www.w3.org/2000/svg" height="14">
    <style type="text/css">
        @import url(https://fonts.googleapis.com/css?family=Droid+Sans+Mono);
    <linearGradient id="g1">
      <stop stop-color="#222" offset="0%"/>
      <stop stop-color="#444" offset="100%"/>
    <linearGradient id="g2">
      <stop stop-color="#2a2" offset="0%"/>
      <stop stop-color="#0a0" offset="100%"/>

    <!-- Extra rectangles on left & right for the rounded corners -->
    <rect x="0" y="0" width="16" height="14" fill="#222" rx="4" ry="4"/>
    <rect x="129.6" y="0" width="8" height="14" fill="#0a0" rx="4" ry="4"/>

  <rect x="4" y="0" width="87.2" height="14" fill="url(#g1)" />
  <rect x="91.2" y="0" width="42.4" height="14" fill="url(#g2)" />

  <text x="6.0" y="10" font-size="10.5" font-family="'Droid Sans Mono', monospace" text-anchor="start" fill="#fff">Ruby on Rails</text>
  <text x="93.2" y="10" font-size="10.5" font-family="'Droid Sans Mono', monospace" text-anchor="start" fill="#fff">1 vote</text>
  • Hi @horatio, I've updated my question as feedback to your answer. Also, I'd like to clarify that I'm embedding the image inside a page using the <img /> tag, so external CSS shouldn't affect (AFAIK). I've also included screenshots. Thanks. – Vikrant Chaudhary Jun 21 '12 at 7:53
  • I edited the answer with a few things. (1) it is an xml file and you can see the CSS declaration pointing to fonts.googleapis.com (line 6). This is not being honored for some reason, and the result is that your browser does not have the font file. (2) The screen capture is what the SVG file looks like (with proper typeface). However, the "embedded version" displayed in the body of your question above looks to be the courier typeface and looks very similar to your screen captures. – horatio Jun 21 '12 at 18:13

Your Answer

