166

Let's say I have the SVG file:

<svg width="1024" height="768" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <text x='20' y='60' style="font-size: 60px">b</text>
    <text x='100' y='60' style="font-size: 60px">a</text>
</svg>

I want to somehow align the top of a and b. Actually, I want my positioning to be according to the roofline instead of baseline!

semekh
  • 3,867
  • 2
  • 24
  • 34

5 Answers5

287

According to SVG spec, alignment-baseline only applies to <tspan>, <textPath>, <tref> and <altGlyph>. My understanding is that it is used to offset those from the <text> object above them. I think what you are looking for is dominant-baseline.

Possible values of dominant-baseline are:

auto | use-script | no-change | reset-size | ideographic | alphabetic | hanging | mathematical | central | middle | text-after-edge | text-before-edge | inherit

Check the W3C recommendation for the dominant-baseline property for more information about each possible value.

Mariano Desanze
  • 7,847
  • 7
  • 46
  • 67
toutankh
  • 2,871
  • 2
  • 12
  • 2
  • 13
    This fixed my problems with Firefox (which was not working with the "alignment-baseline" property). The "dominant-baseline" works on Chrome & Firefox. Thanks! – Mariano Desanze Sep 19 '14 at 22:40
  • 5
    Except that this doesn't work in any version of IE at this point, so it's really not that useful for many real-world applications, unfortunately. – Yona Appletree Oct 30 '15 at 21:10
  • 3
    Since IE doesn't support either dominant-baseline, or alignment-baseline, you can check support for the feature like so `element.hasAttribute('dominant-baseline')`, and if it returns false apply `dy=-0.4em` as outlined in this answer http://stackoverflow.com/a/29089222/2296470 – Tigran May 04 '16 at 14:32
  • 1
    dominant-baseline: central worked in my case. thanks! – Liam Mitchell Jan 26 '17 at 04:52
  • none of these seem to actually vertically center bare svg text... it's close, but not quite spot on... – Michael Nov 03 '17 at 02:48
  • 2
    be aware that [dominant-baseline](https://msdn.microsoft.com/en-us/library/gg558060(v=vs.85).aspx) is not supported by IE10-12 **and** Edge16 – japrescott Mar 02 '18 at 10:03
  • `dominant-baseline:central;` in my – Sideways S Feb 13 '19 at 17:10
  • works nicely with transformations & scaling - https://jsfiddle.net/wbqrv1cu/ (at least in Chrome) – jave.web Oct 08 '19 at 10:15
131

The alignment-baseline property is what you're looking for it can take the following values

auto | baseline | before-edge | text-before-edge | 
middle | central | after-edge | text-after-edge | 
ideographic | alphabetic | hanging | mathematical | 
inherit

Description from w3c

This property specifies how an object is aligned with respect to its parent. This property specifies which baseline of this element is to be aligned with the corresponding baseline of the parent. For example, this allows alphabetic baselines in Roman text to stay aligned across font size changes. It defaults to the baseline with the same name as the computed value of the alignment-baseline property. That is, the position of "ideographic" alignment-point in the block-progression-direction is the position of the "ideographic" baseline in the baseline-table of the object being aligned.

W3C Source

Unfortunately, although this is the "correct" way of achieving what you're after it would appear Firefox have not implemented a lot of the presentation attributes for the SVG Text Module ('SVG in Firefox' MDN Documentation)

Michael Currie
  • 13,721
  • 9
  • 42
  • 58
Simon West
  • 3,708
  • 1
  • 26
  • 28
  • Had no luck with that. Could you provide an example? – semekh Sep 03 '12 at 15:28
  • 2
    In my opinion the best answer, as it answered mine without having to navigate to a wall-of-text page.I wanted to display my text at y = 0, but it was off screen, so I used a CSS rule "alignment-baseline: hanging", and it did exactly what I was looking for, text at highest point in the SVG container, without a single pixel being offscreen. – R. Hill Apr 12 '13 at 15:06
  • 1
    @SeMeKh: Hmm incidentally, it worked for me on Chromium, but now I just verified that the same doesn't not work on Firefox. So it appears this property is not supported consistently across browsers as of now. – R. Hill Apr 12 '13 at 18:01
  • @R.Hill Looking at the [MDN docs](https://developer.mozilla.org/en/docs/SVG_in_Firefox) it appears your correct "Various presentation attributes don't work (alignment-baseline, ...." updated answer to reflect this fact. – Simon West Apr 15 '13 at 12:52
  • @SeMeKh "alignment-baseline: hanging" seems to work on firefox. What exactly didn't work there? – matanster May 17 '14 at 19:47
  • `text-before-edge` apparently doesn't register with Firefox. – Joel DeWitt Oct 28 '16 at 16:25
  • 2
    @R.Hill Here is the bugreport for firefox which was opened over 11 years ago https://bugzilla.mozilla.org/show_bug.cgi?id=308338 Btw: What is the difference between 'middle' and 'central'? – mxmlnkn Oct 31 '16 at 13:56
  • In HTML "middle" is vertical alignment, and "center" is horizontal alignment. I'm not sure they are the same in SVG however. – posfan12 Dec 28 '16 at 01:10
  • 11
    Upvoted by mistake, and because I've made the same mistake before, I can't undo it. ☹ `alignment-baseline: central` does _not_ work for SVGs in FireFox, and that seems to be by design. `dominant-baseline: central` works in every browser I've tried so far, as indicated in this answer: https://stackoverflow.com/a/15997503/1450294 – Michael Scheper Jan 08 '18 at 23:04
  • The more upvoted `dominant-baseline` seems to be by far the better answer, in that it actually works cross-browser, even in 2021. – Mike 'Pomax' Kamermans Mar 19 '21 at 22:50
56

attr("dominant-baseline", "central")

user1087079
  • 1,358
  • 12
  • 10
  • 2
    This aligns by the center of the character (as much as the font glyphs play nicely), not sure how this is an answer here to this question. – matanster May 17 '14 at 19:29
  • 4
    This is d3 or jquery method of assigning attributes – 111 Nov 20 '14 at 16:55
  • 1
    This solution puts the baseline in the vertical centre of the text. So the y coordinate is at the vertical centre. This was the answer I was looking for. Thanks. – Henry Oct 31 '18 at 21:29
  • 2
    The core of the answer is correct - set dominant-baseline attribute to central, however attr() is not a native JS function and there is no explanation at all. – jave.web Oct 08 '19 at 09:59
  • The question was asking for a "rooflike" alignment, not "central". I assume the correct `dominant-baseline` value that actually answers the original question is `hanging`. – bluenote10 Jan 17 '21 at 22:22
37

If you're testing this in IE, dominant-baseline and alignment-baseline are not supported.

The most effective way to center text in IE is to use something like this with "dy":

<text font-size="ANY SIZE" text-anchor="middle" "dy"="-.4em"> Ya Text </text>

The negative value will shift it up and a positive value of dy will shift it down. I've found using -.4em seems a bit more centered vertically to me than -.5em, but you'll be the judge of that.

whyoz
  • 5,168
  • 47
  • 53
  • 5
    Thank you for having the only answer that works in IE. It's a shame we have to do this, but the other answers wasted me a significant amount of time getting everything working in Chrome/FF, then finding that it doesn't work in IE during browser testing. – Yona Appletree Oct 30 '15 at 21:11
  • Nice and simple decision! And we should remember to remove "alignment-baseline" attribute to omit its influence on the text position in browsers which support it. – YaTaras Oct 13 '17 at 08:36
7

After looking at the SVG Recommendation I've come to the understanding that the baseline properties are meant to position text relative to other text, especially when mixing different fonts and or languages. If you want to postion text so that it's top is at y then you need use dy = "y + the height of your text".

brichins
  • 3,825
  • 2
  • 39
  • 60
rjax
  • 71
  • 1
  • 1
  • Appreciate the link to the spec, some really useful reading there. Wasn't aware of the (linked) `""` option for instance (allows per-character manipulation) – brichins Dec 14 '16 at 22:09