I would like to horizontally centre align more than one line of text.
The following approach works in Firefox 68.0.2
path { stroke: #000; }
text { fill: #000; }
<svg width="400" height="120">
<path id="p1" d="M10,40l250,0" />
<text text-anchor="middle">
<textPath href="#p1" startOffset="50%">
<tspan x="0" dy="1.4em">this is the first line</tspan>
<tspan x="0" dy="1.4em">and this is the second</tspan>
</textPath>
</text>
</svg>
However, in Chrome Version 77.0.3865.90, both lines are rendered to the left. It looks as though the combined length of the two <tspan>
is used to calculate the centre point.
I can make it work in both browsers by using two separate <text>
elements:
path { stroke: #000; }
text { fill: #000; }
<svg width="400" height="120">
<path id="p1" d="M10,40l250,0" />
<text text-anchor="middle">
<textPath href="#p1" startOffset="50%">
<tspan x="0" dy="1.4em">this is the first line</tspan>
</textPath>
</text>
<text text-anchor="middle">
<textPath href="#p1" startOffset="50%">
<tspan x="0" dy="2.8em">and this is the second</tspan>
</textPath>
</text>
</svg>
(I also tried using two <textPath>
within the same <text>
parent, but the behaviour of dy
is also different between the two browsers)
My questions are:
<text>
elements?I believe Chrome is doing the correct thing here - other than the missing "a". :-/
In SVG 1.1, the interaction of the startOffset
and x
attributes wasn't well defined, and browsers did all different things.
However, in SVG 2, an attempt to fully describe the text layout algorithm for <textPath>
elements has been made. You can find it here:
https://svgwg.org/svg2-draft/single-page.html#text-TextpathLayoutRules
In there it says:
For text-anchor:middle, startpoint-on-the-path is the point on the path which represents the point on the path which is [ ‘startOffset’ minus half of the total advance values for all of the glyphs in the ‘textPath’ element ] distance along the path from the start of the path
Then later, it says:
When the inline-base direction is horizontal, then any ‘x’ attributes on ‘text’ or ‘tspan’ elements represent new absolute offsets along the path, thus providing explicit new values for startpoint-on-the-path.
In other words, your x="0"
attributes are overriding the startOffset
and text-anchor
settings.
So being more simple and explicit, as you are in your second SVG, is the way to go.