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

Using specific instance for @font-face in TTF file containing multiple instance

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

我有一个带有 @font-face 的样式表,它引用了一个包含多个面孔的单个 TTF 文件。在 Windows 字体查看器中,如果我循环“下一步”,它看起来像这样(抱歉,GIF 变得混乱,选择了错误的编码参数,不想重做,但你明白了):

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

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

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

:root {
  font-family: TestFont;
}

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

我的问题是:如何指定我想改用“压缩”变体?

这是一个 fiddle。我只想为这个 post 将字体作为数据 URI 嵌入,但它太大而无法在此处 post (编码大约 500kB)所以它在这里:https://jsfiddle.net/qugoeam5/

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

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

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

  1. 打开字体设置

  2. 搜索并select“可用字体”下的字体

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

  4. 在这里你可以select实例然后通过每个轴来查看它的标签和值:

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

至于 CSS,兼容性目前参差不齐。 CSS3 无法 select 命名实例。它也没有正式支持设置轴值。不过,CSS4 正在标准化对两者的支持 (font-named-instance and font-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 位)。 YMMV:

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

这意味着,至少 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;
    }
    

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

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