To vertically align a tspan
element inside a text
element in SVG, the CSS properties alignment-baseline
and dominant-baseline
work great in Chrome and in FF, respectively. So far so good.
With Internet Explorer it gets a bit crazy:
alignment-baseline
is supportedalignment-baseline
as well as dominant-baseline
for tspan
, but they do not work with any values
This wouldn't be such an issue for IE9 (one could simply hack the desired alignment), but since I want to get away from browser detection, I would like to know:
Thanks!
The vertical-align property can be used in two contexts: To vertically align an inline element's box inside its containing line box. For example, it could be used to vertically position an image in a line of text. To vertically align the content of a cell in a table.
The default value of vertical-align (if you declare nothing), is baseline. Images will line up with the text at the baseline of the text.
Answer. Answer: The vertical-align CSS property sets vertical alignment of an inline, inline-block or table-cell box.
I have no idea why IE doesn't support alignment-baseline, let alone why you're getting such mixed information.
You can sort of hack the same behaviour using the dy
attribute and font-based units ("em" and "ex"). It works pretty well if you just want to center a specific text element on a point.
<text x="50%" y="50%" dy="0.5ex" text-anchor="middle">
This text will be centered in your coordinate system!
</text>
But the problem with dy
is that -- unless y
is also set explicitly for the same element -- it is calculated relative to the position of the previous character. So if you want to center a text span relative to the surrounding spans, you have to first adjust for any previous offset and then set the new offset. The resulting code isn't pretty:
<text x="50%" y="25%" font-size="150%">
<tspan dy="0.5ex">Large font with</tspan><tspan
dy="-0.5ex"> <tspan
font-size="50%" dy="0.5ex">small font<tspan
dy="-0.5ex"> </tspan></tspan></tspan><tspan
dy="0.5ex">embedded.</tspan>
</text>
<text x="50%" y="75%" font-size="75%">
<tspan dy="0.5ex">Small font with</tspan><tspan
dy="-0.5ex"> <tspan
font-size="200%" dy="0.5ex">large font<tspan
dy="-0.5ex"> </tspan></tspan></tspan><tspan
dy="0.5ex">embedded.</tspan>
http://fiddle.jshell.net/awj49/
Rendering in IE11:
(gray lines mark the reference y coordinate)
If you can, it makes much cleaner code to just explicitly set the y
attribute on each tspan:
<text x="50%" font-size="150%">
<tspan y="25%" dy="0.5ex">Large font with</tspan>
<tspan font-size="50%" y="25%" dy="0.5ex">small font</tspan>
<tspan y="25%" dy="0.5ex">embedded.</tspan>
</text>
<text x="50%" y="75%" font-size="75%">
<tspan y="75%" dy="0.5ex">Small font with</tspan>
<tspan font-size="200%" y="75%" dy="0.5ex">large font</tspan>
<tspan y="75%" dy="0.5ex">embedded.</tspan>
</text>
http://fiddle.jshell.net/awj49/1/
The final rendering is the same:
IE doesn't seem to support any vertical alignment CSS properties. A tspan
is rendered with a default of what approximates alignment-baseline: central
. Therefore, browser detection and polyfilling seems to be the only option just now to have your elements render the same across all browsers.
I adapted AmeliaBR's brilliant answer by manually adding to the y
attribute of the parent text
element to the desired difference of the font height in pixels (+50% of the font height = hanging
, -50% = before-edge
...). Like so:
d3.selectAll('text').each( function()
var text = d3.select(this);
var dy = text.attr('y') || 0;
var h = text.style('font-size').replace('px', '') * 1;
var nh = (dy * 1) + (h / 2);
text.attr('y', nh);
});
I've used d3 here, but obviously this works with any JS library or pure JS DOM-selection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With