如何在IE9中垂直居中SVG文本

问题描述:

为了在SVG中垂直对齐文本,必须使用dominant-baseline属性. 这已经在SO(在SVG中对齐文本)上进行了讨论,并且是规范.

In order to align text vertically in SVG one has to use the dominant-baseline attribute. This has already been discussed on SO (Aligning text in SVG) and is part of the specification.

我的问题出在IE9上,它显然不支持dominant-baseline 和一堆

My problem is with IE9 which apparently does not support dominant-baseline and a bunch of other things.

您对在IE9中如何近似dominant-baseline: central有任何想法吗?

Do you have any ideas on how to approximate dominant-baseline: central in IE9?

这里是可在FF和Chrome中运行的示例.它在IE9,Opera 11中不起作用.Windows上的Safari不支持central,但是支持middle,这仍然很好.

Here is a sample that works in FF and Chrome. It does not work in IE9, Opera 11. Safari on Windows doesn't support central, but supports middle which is still good.

<?xml version="1.0"?>
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
    <path d="M 10 100 h 290" stroke="blue" stroke-width=".5" />
    <text x="40" y="100" font-size="16" style="dominant-baseline: auto;">
        XXX dominant-baseline: auto; XXX
    </text>

    <path d="M 10 200 h 290" stroke="blue" stroke-width=".5" />
    <text x="40" y="200" font-family="sans-serif" font-size="15" style="dominant-baseline: central;">
        XXX dominant-baseline: central XXX
    </text>
</svg>

这是一个巨大的技巧,但是我们可以通过考虑字体大小来估计垂直中间位置.

This is a giant hack, but we can approximate the vertical middle position by taking the font size into account.

规范对central的定义如下:

中央

这标识了计算的基线 在EM框的中央.

This identifies a computed baseline that is at the center of the EM box.

我们可以使用已知字体大小的EM box并测量其边界框以计算中心.

We can take an EM box of known font size and measure its bounding box to compute the center.

<?xml version="1.0"?>
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
    <path d="M 10 100 h 290" stroke="blue" stroke-width=".5" />
    <text id="default-text" x="20" y="100" font-size="5em">
        M
    </text>
    <script>
        window.onload = function() {
            var text = document.getElementById("default-text"),
                bbox = text.getBBox(),
                actualHeight = (100 - bbox.y),
                fontSize = parseInt(window.getComputedStyle(text)["fontSize"]),
                offsetY = (actualHeight / 2) - (bbox.height - fontSize);

            text.setAttribute("transform", "translate(0, " + offsetY + ")");
        }
    </script>

    <path   d="M 10 200 h 290" stroke="blue" stroke-width=".5" />
    <text   id="reference-text" x="20" y="200" font-size="5em"
            style="dominant-baseline: central;">
        M
    </text>
</svg>

显然,代码可以更简洁,但这只是概念验证.

Obviously, the code can be much cleaner, but this is just a proof-of-concept.