首页 > 解决方案 > 在包含多个实例的 TTF 文件中为 @font-face 使用特定实例

问题描述

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

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

在此处输入图像描述

该文件具有 .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/

标签: htmlcssfontstruetypeopentype

解决方案


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

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

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

  1. 打开字体设置

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

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

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

    在此处输入图像描述

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

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

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

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

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

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

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

  • 除了兼容性,这些都相当于重量:
    • [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 是的 是的 是的
[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 出现,理论上这一切都会简单得多。


推荐阅读