使用 CSS 修复自定义字体行高

Fix custom font line-height with CSS

在我正在开发的新网络应用程序上使用自定义字体时,我遇到了一个奇怪的问题。

此自定义字体 (FF DIN) 似乎具有自然的垂直偏心行高,这迫使我放置一些 padding-top hack 以补偿按钮和输入等元素的顶部 space。

示例:绿色字体 (Helvetica Neue) 正确对齐,我们使用的自定义字体 (FF DIN) 垂直偏离中心:

是否有任何已知方法可以自然地解决 CSS 上的居中问题,以某种方式强制字体基线行为?

谢谢。

这是我最近遇到的事情。由于某种原因,我使用的字体基线没有对齐,所以我对齐到底部并增加行高而不是添加填充。

这就是我解决问题的方法,如果您有 link 代码笔,我可以检查它是否适合您,或者其他解决方案是否更好。

p {

    vertical-align: text-bottom;
    line-height: 1.5;

}

这里的问题不是行高,而是字形的垂直放置,尤其是文本基线的位置。这是字体设计师决定的;设计师绘制字形并将它们放置在 em 方块中,em 方块是高度等于(或定义为)字体高度的概念设备。特别是,设计者决定一方面在基线以下,另一方面在大写字母高度之上有多少 space。通常这些 space 相等或几乎相等,但它们不一定相等。如果它们有很大不同,则字体的预期用途可能是特殊的,并且不包括图像中显示的用法。这表明应该重新考虑字体选择,但我们假设它是固定的。

有几种方法可以解决这个问题。如果字母下面的space太多,减少line-height会变小,但也会影响上面的space。顶部填充在某种意义上有帮助,但它增加了元素占用的总高度。你也可以玩 vertical-align,但它会影响线框的高度。

可能最简单的方法是使用相对定位,假设问题处理的是单行文本。相对定位只是以指定的方式替换内容,而不会影响布局。为此,您需要一个包装器,即一个包含文本的元素,这样您就可以只替换文本,而不是背景。

下面的demo使用了Google字体Candal,它也有类似的问题,但是方向不同:基线太低。为满足原始问题而对这种方法进行的修改应该是显而易见的,但需要根据经验确定确切的位移量(或根据使用字体检查器从字体文件中提取的信息)。当然,这里应该使用 em 单位,即使你以像素或磅为单位设置字体大小(这样如果有一天字体大小发生变化,代码也不需要更改)。

<link href='http://fonts.googleapis.com/css?family=Candal' rel='stylesheet'>
<style>
div { font-family: Candal }
div { background: lightgreen; font-size: 200%}
</style>
<p>What we have got initially:
<div>BRAKE HOSE AND AIR CHAMBER</div>
<p>Reducing line height (even “setting solid”) does not really help:
<div style="line-height: 1">BRAKE HOSE AND AIR CHAMBER</div>
<p>But displacing the text upwards by 0.1em does:
<div><span style="position: relative; bottom: 0.1em">
BRAKE HOSE AND AIR CHAMBER</span></div>

我以前也遇到过这个问题,甚至不同的浏览器给出了不同的行高!我认为它发生在使用 webfont 生成器时,据我所知只能通过使用不同的行高来修复。

你试过 fontsquirrel 吗?有一些选项有不同的结果。

http://everythingfonts.com/font-face

http://www.font2web.com/

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

https://www.web-font-generator.com/

最后,我自己手动修复了字体,使用这个答案的帮助:

UIButton custom font vertical alignment

在 Chrome 中,我发现如果您使用字体声明。您可以通过在 HTML 中调用 style="" 来解决行高问题,或者在 CSS.

中的字体声明之后简单地声明行高

我认为 Chrome 在呈现自定义字体之前不知道如何计算行高。

最近 CSS 中引入了新的 font-face descriptor 属性用于此类目的。它们允许 CSS 覆盖字体文件本身包含的一些信息。

在字体的 @font-face 描述中,您现在可以添加:

对于另一个答案中使用的这种随机 google 字体,似乎对 ascent-override 稍作调整是人们可能想要的。

@font-face {
  font-family: 'Candal Without Override';
  font-style: normal;
  font-weight: 400;
  src: url(https://fonts.gstatic.com/s/candal/v15/XoHn2YH6T7-t_8c9BhQIldUhlg.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Candal With Override';
  font-style: normal;
  font-weight: 400;
  src: url(https://fonts.gstatic.com/s/candal/v15/XoHn2YH6T7-t_8c9BhQIldUhlg.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  ascent-override: 90%;
}

p {
  background: lightgreen; 
  font-size: 200%;
}

.regular {
  font-family: 'Candal Without Override';
}

.override {
  font-family: 'Candal With Override';
}
<div>with <code>ascent-override</code></div>
<p class="override">BRAKE HOSE AND AIR CHAMBER</p>
<div>without <code>ascent-override</code></div>
<p class="regular">BRAKE HOSE AND AIR CHAMBER</p>