Easily center text vertically, with SVG!

These days, we have a number of different ways to vertically align text in a container of variable dimensions:

  • Table display modes
  • Flexbox
  • inline-block hacks
  • Wrapping the text in an extra element and absolutely positioning it
  • …and probably many others I’m forgetting

However, often comes a time when neither is suitable, so here I am, adding yet another option to the list. Of course, it comes with its own set of drawbacks, but there are cases where it might be better than the existing solutions.

It all started when I discovered the text-anchor SVG property. It determines where the x and y attributes on <text> elements refer to. The magic starts when you set it to “middle”, then the x and y attributes refer to the center of the text. So, if you set those to 50%, they refer to the center of the SVG graphic itself, and if you set the SVG width and height to 100%, the text basically sits in the center of the <svg>’s container, which could be any HTML element!

One issue was that this centered the baseline of the text, so I tried to find a way to shift the baseline appropriately. Setting dominant-baseline: middle; on the <text> element seemed to fix it, but it looks like IE doesn’t support that. I ended up adding dy=”.3em” to the <text> element, which fixes it but might need to be adjusted if you change the line-height.

In addition, this method has the following drawbacks I can think of:

  • Extra markup (namely 2 elements: <svg> and <text>)
  • If the text is more than one line, it won’t automatically wrap, you have to do it manually.
  • Some new-ish CSS text properties may not be applied. For example, text-shadow is applied in Chrome but not in Firefox, since technically, it’s still not a part of the SVG spec.
  • You need to duplicate the text color as a fill property, since SVG does not understand the color CSS property. No need to duplicate anything, just use fill: currentColor; (thanks GreLI!)

However, it has a few advantages too:

  • You don’t need to change anything on the parent HTML element
  • Degrades gracefully in non-SVG browsers
  • Should be perfectly accessible and won’t break SEO
  • Works perfectly in IE9, unlike Flexbox
  • You can include any kind of SVG styling on the text. For example, strokes!

You can see and play with the result in the dabblet below:

Verified to work in at least Chrome, Firefox, IE9+. Hope it’s useful, even though it won’t be a good fit in every single use case.

  • maxw3st

    Nice technique. Thanks. I’ve been playing around with SVGs and animation, but didn’t realize I could add the text tags inside them.

  • Terrific! I’ll try it right now in the www2013 site that we’re developing!

    • Awesome! I’d love to see it, if it’s private feel free to email me (you can find my email address on the about page). Feel free to ask if you run into any issues.

  • .

    I would not even have dreamt of actually using the text and svg elements… very cool. Since you’re there already… let me give you a challenge. Do you think it’s possible to create a replacement for fittextjs with this? (Sorry Trent, Dave and Reagan ;P)
    I’ve been looking at w3c’s svg attributes right now, feels like you just showed me some undiscovered land to explore, thanks :}

  • Working on mobile and desktop Safari as well 🙂

  • Hi, the idea to use svg is very original! With ie9 support svg is definitely worthy of some study. Still am I wrong or your technique only works for single line texts? This would make simply setting line-height much easier.

    • It’s much easier for single line texts. I think you could get it to work for multi-line texts, but you need to wrap it manually and adapt the technique a bit.

      • Josh Bambrick

        Fair point but you probably ought to mention that in the article since it is almost always (in my experience) the best solution. Suggesting ‘table display modes, flexbox inline-block hacks, wrapping the text in an extra element and absolutely positioning it’ above just setting the line-height, will send people searching for a solution to this issue down the wrong tracks

  • .

    I went in, looked at what I could find and created a fittext.js alternative with pure SVG myself.
    Sure, it’s not perfect, I’m simply assuming that the resizing itself will be proportional.
    But it should work well with a responsive site. I’ve modified your dabblet to suit the needs. Thanks for leading me to this! SVG is wicked.


    • Yay, this looks great! Yes, SVG is wicked indeed. A lot of untapped potential we’re only now starting to discover.

  • This is awesome, it only lacks one feature to solve one problem i’ve facing. Would it be possible to resize the text (stil in one line) so it never be bigger than the SVG element?
    As it is now it simply overflows.

  • It doesn’t do multiple line wrapping =( Is that a thing in SVG?

  • My fav vertical align method is with :before http://css-tricks.com/centering-in-the-unknown/

  • C’mon guys, this problem is already solved. Why we should create new solutions which create new problem?

    • innovation breeds change. if people like Lea weren’t trying new solutions we would still be using tabels to layout pages.

      • Lukyvj


  • > You need to duplicate the text color as a fill property, since SVG does not understand the color CSS property.

    Actually, you don’t have to duplicate. You can use the “fill: currentColor” rule, and it will inherit a value from the parents ‘color’ attribute.

    • Thanks, post updated!

      • I see the update on Dabblet but not in the post itself. Is it deployed yet?

        • Odd, I was certain I saved. Did it again, thanks.

        • Great! Now it works.

  • Pingback: Easily center text vertically, with SVG!()

  • Pingback: Tweet Parade (no.13 Mar 2013) | gonzoblog()

  • I’m just directly creating an SVG image and this was super helpful. Thank you for putting it in an article 🙂

  • This is what I’ve been looking for. Thank you!

  • Frank

    Lea like your post too gud

  • Mike Gledhill

    Here’s the JavaScript function I wrote, to do some pseudo-word-wrapping on an SVG text label:

  • Very useful and supportive article. I wish I can do all of that in a short period of time.

  • Pingback: A Compendium of SVG Information | Lunarium Design()

  • Pingback: A Compendium of SVG Information | Vips()

  • fer

    I love your page , what a great taste , thanks for sharing !

  • Pingback: How to Use SVG to Create Responsive Texts & Filters - CodeCondo()

  • Derek

    Thank you! Finally, I can easily center the text in these donut charts :{

  • Pingback: Metrology()

  • Pingback: Engineering Notes()

  • Pingback: angara fahise()

  • Pingback: Opulence for life scam()

  • Pingback: best muscle building steroids()

  • Pingback: Facebook Live()

  • Pingback: taxi service()

  • vinneyk

    Just now dipping my toe into the svg pool. This article helped me actually start to manipulate the elements in a meaningful way. Thanks!

    – Old Dog

  • Pingback: 4cyn5et4m5t94c5t9m4vn54cx65()

  • Pingback: http://falschgeldkaufen.blogspot.com/2017/01/wo-kann-ich-falschgeld-kaufen.html()