使用“f”和“i”时,Safari字距问题

5

我正在运行OS X 10.10.3上的Safari 8.0.5。

每当使用字符"f"和"i"紧挨在一起时,我遇到了字母间距的问题。我猜这是Safari的一个bug,并已将其提交给Apple,但也想看看是否可以找到临时解决方法。

HTML输出将短语"The fish is large"分为两个不同的字体。为了突出问题,我增加了每个字符之间10px的字母间距。

HTML:

<div class="p1">
    The fish is large
</div>
<div class="p2">
    The fish is large
</div>

CSS:

div { letter-spacing: 10px; margin-bottom: 10px; }

div.p1 { 
    color: #009900;
    font-family: Helvetica;
}
div.p2 {
    color: #000099;
    font-family: Arial;
}

这是在Safari中上述输出的样子:

Safari Letter Spacing Issue

为了测试目的,我在"f"和"i"字符之间添加了一个HTML注释,这似乎起作用了。
<div class="p1">
    The f<!----->ish is large
</div>

像这样输出:

HTML Comment Version

虽然从技术上讲这是可行的,但对我来说并不是一个理想的解决方案,因为这里的内容实际上是由所见即所得编辑器生成的。

似乎问题只出现在 "f" 和 "i" 相邻时。我不确定这些字母在 Safari 中是否有特殊含义,但它们是英语中非常常见的字母序列,因此它们不应该有如此小的关键字。

我还尝试添加了这个:

 -webkit-font-feature-settings: "kern";

那确实把"s"推到了右边,但"f"和"i"仍然挤在一起。

webkit font features

大写的“F”没有同样的问题:

Capitalized F

而跟在“fi”后面的字符似乎并不重要。我可以将其更改为任何其他字符,问题仍然存在。

Other letters after fi

如果“fi”出现在单词中间,它也会执行相同的操作:

fi mid-word

我确认了这个问题在我的iPhone 6 Plus上运行最新版本的Safari时也存在,所以我怀疑这不仅仅是我的问题。

为了说明这个问题,我创建了一个jsfiddle,其中包含必要的HTML和CSS,希望能在您那边重现这个问题。 https://jsfiddle.net/38keruv7/4/

有人有任何想法可以解决这个问题,而不涉及要求我的客户在WYSIWYG编辑器中插入HTML注释吗?

我想我可以在输出数据之前扫描和替换特定组合,但是当处理更大块的数据时,这似乎是一种相当低效的服务器资源使用方式。

1个回答

11

看起来你发现了Safari的一个bug。连接在一起的“fi”是字体连字。CSS3有一个font-variant-ligatures属性,可用于控制它们;Safari使用-webkit前缀支持它。看起来-webkit-font-variant-ligatures: no-common-ligatures;至少在Safari 8.0.3中解决了这个问题:

div {
    -webkit-font-variant-ligatures: no-common-ligatures;
    letter-spacing: 10px;
    margin-bottom: 10px;
}

这里是更新后的代码片段:https://jsfiddle.net/38keruv7/5/

如果你还有困难,这里有一个相关的问题,它说rendering: optimizeSpeed;也可以解决这个问题:Safari中字母连接的问题


我尝试了渲染选项:optimizeSpeed;,但似乎没有起作用。但是no-common-ligatures声明完美地解决了问题。谢谢。 - David Stinemetze
1
换句话说,这实际上不是一个错误。如果字体默认使用常见的连字,则文本整形器将自动应用连字(将两个字母“f”和“i”的序列转换为单个字母“fi”)。这不是Safari控制的事情,除非您明确告诉它,否则它会自动应用。因此,如果您想绕过它,可以使用CSS3功能指令,如此答案所示。 - Mike 'Pomax' Kamermans
1
不,这是正确的行为。浏览器要求字体呈现一系列代码点,没有任何关于如何执行此操作的覆盖方式,文本渲染引擎返回一个由字体包含的指令确定的不同字形的列表,仅按照其间距和字距进行排列。然后CSS生效,应用字母间距,在“fi”、“s”和“h”之间添加间距。因此,如果您不希望出现连字,您可以强制使用“no-common-ligatures”,以便文本引擎知道绕过它们,甚至使用“liga=0”或类似方法关闭所有连字。 - Mike 'Pomax' Kamermans
1
@Mike'Pomax'Kamermans 那为什么“fi”和“s”之间没有空格呢? - David Stinemetze
1
可能是一个 bug,但似乎是一个单独的问题,例如“连字+下一个字母”没有正确应用 CSS 字母间距,而不是“f+i”之间没有字母间距,因为它们被默认替换了。 - Mike 'Pomax' Kamermans
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接