css - SVG 或 HTML 中像素完美一致的文本宽度

标签 css svg cross-browser typography

jsFiddle 上查看此演示(或 hosted here ):

  • 我有一个大致 (99.99%) 圆形的 svg 路径
  • 沿着这条路径,我使用“textpath”svg 元素放置文本
  • 我希望文本的结尾尽可能准确地(最好是像素完美)与开头相遇,以便形成一个连续的文本循环

这是代码的摘录(去掉了所有文本值):

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" viewBox="0 0 480 480" preserveAspectRatio="xMidYMid" height="100%"
width="100%">
    <defs>
        <style type="text/css">
            /* for some reason, SVG font import doesn't work in Chrome or Firefox! */
            @font-face {
                font-family: Libertine;
                src: url(LinLibertine_R.svg#LinLibertineO);
            }
            @font-face {
                font-family: Libertine2;
                src: url(LinLibertine_Rah.ttf);
            }
            /* Chrome seems to round to the nearest 0.5 em; also, does not display em-widths consistently with Firefox (though px-widths are consistent) */
            .ex1 {
                font: 0.85em Libertine2;
            }
            .measurement {
                font: 1.0em monospace;
            }
        </style>
        <text id="day1">...</text>
        <text id="day2">...</text>
        <text id="day3">...</text>
        <text id="day4">...</text>
        <text id="day5">...</text>
        <text id="day6">...</text>
        <text id="day7">...</text>
    </defs>
    <g transform="translate(240,240)">
        <g transform="translate(-240,-240)">
            <circle r="1" cx="240" cy="27" fill="black" />
            <path id="circle" d="M 240,20 a 220,220, 0 1,1 -0.0001,0.0000 Z"
            fill="none" stroke="red" stroke-width="0" />
            <path id="inner-circle" d="M 240,40 a 200,200, 0 1,1 -0.0001,0.0000 Z"
            fill="none" stroke="red" stroke-width="0" />
            <text class="ex1" fill="black">
                <!-- this RTL text-along-path is displayed backwards (ie sdrawkcab) in
                Chrome; manual CSS overrides (e.g. unicode-bidi) cause blank/white screen
                -->
                <textPath xlink:href="#circle" method="stretch">...</textPath>
            </text>
            <text class="measurement" fill="grey">
                <textPath xlink:href="#inner-circle" method="stretch">A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 G0 G1 G2 G3 G4 G5 G6 G8 G9</textPath>
            </text>
        </g>
    </g>
</svg>

到目前为止,我能做的最好的事情就是通过 CSS 导入字体,这大致标准化了跨浏览器的宽度。

请注意,Chrome 不会读取微调的字体大小值(例如,它似乎将 0.87em 舍入到 0.85em),并且似乎具有与 Firefox 不同的文本呈现引擎,即使字体大小一致.例如,1em 的字体大小将上例中的内部“测量圆”呈现为 Firefox 中“F9”刻度中的 F,而 Chrome 呈现接近“F4”刻度的开头,这个问题被简化为在字体大小中使用 px 单位时的单个字符宽度差异。

您还会注意到 Chrome 无法正确呈现从右到左 (RTL) 的文本,并且手动 CSS 覆盖(使用“unicode-bidi”和“direction”指令)导致完全失败(根本没有 SVG 呈现) .

不言而喻 - 有很多问题。到目前为止,这是一个有趣的实验,但我们将不胜感激对标准化的任何帮助。

至于我自己的解决方案;我正在考虑使用 LinuxLibertine svg-font 中的字体规范手动指定每个字符的位置,这是找出渲染不一致根源的一种非常俗气的替代方法。

最佳答案

仅依赖于 SVG 和 TTF 的问题在于,您将在非 webkit 浏览器中遇到像素完美问题。其中一些甚至根本不会渲染。 (愚蠢的 IE7)。虽然它不是 100% 完美,但大多数时候 Fontsquirrel 的生成器让我的 webfonts 达到了 99%。

http://www.fontsquirrel.com/tools/webfont-generator

我的经验是针对特定浏览器使用以下格式。这似乎是仅使用 SVG/TTF 的 2 倍工作量,但实际上并非如此,并且在像素完美方面会让您省去很多麻烦。

TTF - 适用于大多数浏览器,但不适合 IE 和 iOS Safari。
EOT - 仅限 IE。
WOFF - 压缩的新兴标准。
SVG - iPhone/iPad。

此 CSS 将涵盖一个系列中的所有格式:

@font-face {
    font-family: 'Libertine';
    src: url('Libertine-webfont.eot');
    src: url('Libertine-webfont.eot?#iefix') format('embedded-opentype'),
         url('Libertine-webfont.woff') format('woff'),
         url('Libertine-webfont.ttf') format('truetype'),
         url('Libertine-webfont.svg#LibertineRegular') format('svg');
    font-weight: normal;
    font-style: normal;
}

然后是连接 HTML:

<style type="text/css" media="screen">
    .ex1 {font: 18px/27px 'Libertine', Arial, sans-serif;}
    }
</style>

希望这对您有所帮助,或者不会让您更加困惑。 :/我倾向于那样做。

关于css - SVG 或 HTML 中像素完美一致的文本宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14789059/

相关文章:

html - 在 IE、Chrome、Safari 中显示时在 Firefox 中具有绝对位置的 IMG 不可见 - 为什么?

css - 跨浏览器样式 CSS 表单 ID

css - 如何将替代的 li 变为粗体?

html - 如何将div定位到父div的右侧和中间

javascript - 使用 Javascript 动态添加时,SVG 元素无法正确缩放

javascript - 为什么在 D3 中将 map 不透明度设置为 0 时整个 SVG 消失了?

css - 底部带有彩色弧形边框的背景图片

javascript - Bootstrap 3.3.4 单个图像不显示在 768 像素以下

css - 在 AngularJS 1 中应用外部 CSS

html - 负 z-index 有副作用吗