在包含多个实例的 TTF 文件中为 @font-face 使用特定实例

问题描述

首先,我不知道 TTF 文件是如何组织的,所以这里的一些术语可能有误。

我有一个带有 @font-face 的样式表,它引用了一个包含多个面的单个 TTF 文件。在 Windows 字体查看器中,如果我循环浏览“下一步”,它看起来像这样(抱歉,GIF 乱七八糟,选择了错误的编码参数,不想重做,但您会发现偏差):

enter image description here

文件的扩展名为 .ttf,但我不确定与 OpenType 的关系(在该窗口中显示为“OpenType”)。

无论如何,我在样式表中是这样引用的:

@font-face {
  font-family: TestFont;
  src: url(...) format('truetype');
}

:root {
  font-family: TestFont;
}

所以,文件中的字体名称是“Bahnschrift”,我要使用的字体是“Bahnschrift Condensed”。除了使用基本的“Bahnschrift”字体外,以上几乎可以正常工作。

我的问题是:如何指定我要使用“精简”变体?

这是一个小提琴。我想为这篇文章嵌入字体作为数据 URI,但它太大而无法在此处发布(大约 500kB 编码),所以它在这里https://jsfiddle.net/qugoeam5/

解决方法

好的,我大致想通了。我有一个基本的解决方案,只是没有确定浏览器兼容性。

所以我所谓的“变体”实际上被称为“instances”。本质上,它们只是命名预设(存储在文件中),用于指定 OpenType 轴集合的值。

Windows 10 内置字体检查器可用于检查给定实例的轴/值集,假设字体已安装在系统上并且是可变字体:

  1. 打开字体设置

  2. 在“可用字体”下搜索并选择字体

  3. 在接下来打开的窗口中,一直向下滚动并单击“可变字体属性”。

  4. 在这里您可以选择实例,然后通过每个轴查看其标记和值:

    enter image description here

因此,对于“Condensed”实例,重量(wght)为 400,宽度(wdth)为 75。

至于 CSS,兼容性目前参差不齐。 CSS3 没有办法选择命名实例。它也没有正式支持设置轴值。不过,CSS4 正在标准化对(font-named-instancefont-variation-settings)的支持。

现在,我不知道这里的历史,但我认为 font-variation-settings(设置单个轴值)可能在某个时候用于 CSS3,然后推迟到 CSS4?或者其他的东西。无论如何,似乎:

  • Edge、Firefox 和 Chrome 支持它,但缺乏 IE 和 Safari 的支持。 Among others
  • 当它在@ 规则之外使用时,似乎有更多的支持。我找不到任何关于原因的信息,我只是观察了一下。

所以这里的一般解决方案是单独设置与您想要的命名实例相对应的轴值(至少在 font-named-instance 滚动之前)。

好消息是,对于某些轴有更广泛支持的高级等效项;在这种情况下,我很幸运:对于这种字体,只设置了粗细和宽度,可以通过 font-weightfont-stretch 设置。不过,现在对 font-stretch 的支持也有点inconsistent(取决于您使用的是命名形式还是 % 形式)。

无论如何,我不能说兼容性,但这里有很多选择。

  • 撇开兼容性不谈,这些都是等价的:
    • [W1] font-weight: 400
    • [W2] font-weight: normal
    • [W3] font-variation-settings: "wght" 400;
  • 这些对于宽度来说都是等价的:
    • [S1] font-stretch: 75%
    • [S2] font-stretch: condensed
    • [S3] font-variation-settings: "wdth" 75;
  • 注意:对于font-variation-settings,如果您设置了多个,则必须一次设置它们:
    • [WS3] font-variation-settings: "wght" 400,"wdth" 75;
  • 再次忽略兼容性,它们可以放在@ 规则中(定义默认值)或其他地方(覆盖默认值),因此这两者也是等效的:
    • 人脸定义中的设置:

      @font-face {
         font-family: "TestFont";
         src: ...;
         [ one of the width settings ];
         [ one of the stretch settings ];
      }
      :root {
         font-family: "TestFont";
      }
      
    • 或者,在@规则之外:

      @font-face {
         font-family: "TestFont";
         src: ...;
      }
      :root {
         font-family: "TestFont";
         [ one of the width settings ];
         [ one of the stretch settings ];
      }
      

因此,将所有这些放在一起,一个选项(尽管具有兼容性)的示例是:

@font-face {
    font-family: 'TestFont';
    src: ...;
    font-weight: normal;
    font-stretch: condensed;
}
:root { 
    font-family: 'TestFont',sans-serif;
}

现在,我还没有在很多浏览器上进行过真正的测试,但以下是上述的组合,它们至少似乎适用于 Chrome 90.0.4430.93(Windows 10,64 位)。赞:

@font-face{} :root{} div{}
[W1] font-weight:400
[W2] font-weight:normal
[W3] font-variation-settings:"wght" 400 没有
[S1] font-stretch:75% 没有 没有
[S2] font-stretch:condensed 没有 没有
[S3] font-variation-settings:"wdth" 75 没有
[WS3] font-variation-settings:"wght" 400,"wdth" 75 没有

这意味着,至少对于 Chrome:

  • 如果你想把两者都放在@font-face中,你必须使用[W1/2] + [S1/2],例如:

    @font-face {
      font-family: "TestFont";
      src: ...;
      font-weight: normal; 
      font-stretch: condensed;
    }
    :root {
      font-family: "TestFont",sans-serif;
    }
    
  • 但是如果你想把两者都放在 :root 或其他元素中,你可以使用任何形式的重量,但你必须使用 font-variation-settings 作为宽度(有效的组合是 [ W1+S3]、[W2+S3] 或 [WS3]),例如:

    @font-face {
      font-family: "TestFont";
      src: ...;
    }
    :root {
      font-family: "TestFont",sans-serif;
      font-weight: normal; 
      font-variation-settings: 'wdth' 75;
    }
    

我不知道其他浏览器的行为是什么;我没有再做任何测试,主要是因为这篇文章有点累人,而且打字的时间比我真正弄清楚这一切的时间长了 100 倍,哈哈。

希望有人指出正确的方向。一旦 CSS4 面世,理论上这一切都会简单得多。