【问题标题】:Using @font-face with an SVG font embedded in the current HTML page将 @font-face 与嵌入在当前 HTML 页面中的 SVG 字体一起使用
【发布时间】:2012-07-12 01:55:33
【问题描述】:

我有一个想要分发的独立 HTML 文档,没有任何外部依赖项。我在本文档中使用了一种非标准字体,只有我的一些用户会安装它。

对于那些没有安装字体的用户,我在<body> 顶部的嵌入式 SVG 文档中包含了字体的副本。 (本例我使用的是单字形字体,实际文档使用的是完整字体。)

<svg style="display: none;"><defs>
  <font id="MyFontElement">
    <font-face font-family="MyFont" />
    <glyph unicode="A" horiz-adv-x="950" d="M0,0L0,100L100,100L100,200L0,200L0,300L100,300L100,400L200,400L200,500L300,500L300,600L400,600L600,600L600,500L700,500L700,400L800,400L800,300L900,300L900,200L800,200L800,100L900,100L900,0L600,0L600,100L700,100L700,200L800,200L800,300L100,300L100,200L200,200L200,100L300,100L300,0L0,0M300,400L600,400L600,500L300,500L300,400Z" />    
  </font>
</defs></svg>

SVG 字体看起来不如普通字体好,所以我只希望在本地未安装该字体的情况下使用 SVG 字体。如果字体是在外部 SVG 文档中定义的,我可以使用它的优先级低于本地安装的字体,如下所示:(fiddle)

<style>
  @font-face {
    font-family: "My Font";
    src: local("My Font"), url("fonts.svg#MyFontElement") format("svg");
  }
</style>
<p style="font: 3em 'My Font';">
    Alphabet
</p>

不幸的是,当前文档中的字体似乎都没有明显的变化:(fiddle)

  src: local("My Font"),
       url("./#MyFontElement") format("svg"),
       url("./#MyFontElement"),
       url("#MyFontElement") format("svg"),
       url("#MyFontElement");

即使没有@font-face 声明,该字体在文档中也已作为MyFont 可用,font-family&lt;font-face /&gt; 中指定。但是,这将在比名为MyFont 的原生字体更高的优先级下使用,因此不是解决方案。

我希望我可以将其称为local("MyFont")... (fiddle)

  src: local("My Font"), /* local */
       local("MyFont"); /* embedded */

...但这也不起作用。

我可以给嵌入的字体一个不同的名称并以较低的优先级使用它,style="font-family: LocalFont, EmbeddedFont",但我允许用户将 sn-ps 从本地文件导入到文档中,这些本地文件将引用该字体仅通过标准名称。导入时可以重写这些引用,但我不喜欢这种解决方案。

如何从 @font-face 声明中引用嵌入在当前文档中的 SVG 字体?

【问题讨论】:

  • 读者应该知道 SVG 字体支持已从 Google Chrome 中删除,并且从未在 Mozilla Firefox 中实现。不过,Apple 似乎仍在 Safari 中维护它。
  • 显然 Firefox 目前确实支持基于 SVG 的字形...嵌入在 OpenType 文件中!哎……

标签: html css svg webfonts


【解决方案1】:

将字体转换为数据 URI 并将其嵌入到 CSS 声明中:(fiddle)

<style>
@font-face {
  font-family: "My Font";
  src: url("data:application/octet-stream;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCIgPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+CiAgPGZvbnQgaWQ9Ik15Rm9udEVsZW1lbnQiPgogICAgPGZvbnQtZmFjZSBmb250LWZhbWlseT0iTXlGb250IiAvPgogICAgPGdseXBoIHVuaWNvZGU9IkEiIGhvcml6LWFkdi14PSI5NTAiIGQ9Ik0wLDBMMCwxMDBMMTAwLDEwMEwxMDAsMjAwTDAsMjAwTDAsMzAwTDEwMCwzMDBMMTAwLDQwMEwyMDAsNDAwTDIwMCw1MDBMMzAwLDUwMEwzMDAsNjAwTDQwMCw2MDBMNjAwLDYwMEw2MDAsNTAwTDcwMCw1MDBMNzAwLDQwMEw4MDAsNDAwTDgwMCwzMDBMOTAwLDMwMEw5MDAsMjAwTDgwMCwyMDBMODAwLDEwMEw5MDAsMTAwTDkwMCwwTDYwMCwwTDYwMCwxMDBMNzAwLDEwMEw3MDAsMjAwTDgwMCwyMDBMODAwLDMwMEwxMDAsMzAwTDEwMCwyMDBMMjAwLDIwMEwyMDAsMTAwTDMwMCwxMDBMMzAwLDBMMCwwTTMwMCw0MDBMNjAwLDQwMEw2MDAsNTAwTDMwMCw1MDBMMzAwLDQwMFoiIC8+ICAgIAogIDwvZm9udD4KPC9kZWZzPjwvc3ZnPgo=") format("svg");
}
</style>
<p style="font: 3em 'My Font';">
    Alphabet
</p>

有一个警告:您不能将 ID 说明符 (#MyFont) 与这样的数据 URI 一起使用。因此,您在编码文件中只能有一个字体,而不是多个并单独引用它们。 (不是你想要的;在每种字体的声明中复制多个嵌入字体的数据会浪费大量空间。)

【讨论】:

  • 好主意,谢谢,效果很好!我已经编辑了您的帖子以包含一个示例和我注意到的警告。但是,如果有 解决方案允许我引用普通嵌入式 SVG 文档中的字体,我不会接受这个答案。
  • 与其使用片段,你不只是用另一种字体声明另一个字体块吗?
  • 是的,这就是我要做的。使用片段将是一个糟糕的决定,但如果它有效,如果我感到非常懒惰,我可能会这样做。我想警告任何其他懒惰的读者,它不会起作用;这对我来说并不明显。
  • 如果是 svgfont,你不应该使用“application/octet-stream”,它应该是“image/svg+xml”。 AFAIK 你可以使用 ID 说明符,至少我很确定我上次尝试在 Opera 中工作。并且您应该始终使用带有 svgfonts 的 ID 说明符,除非您对依赖未指定的行为感到满意。这是一个固定的小提琴,展示了它的外观:jsfiddle.net/fPg3z
  • @ErikDahlström CSS3 字体的 WC3 工作草案告诉我“对于 SVG 字体,URL 指向包含 SVG 字体定义的文档中的元素。如果元素引用是省略,隐含对第一个定义字体的引用”。当我尝试在数据 URL 上指定一个片段时,它会在 Chrome 中中断。哦,亲爱的...
【解决方案2】:

在css中先指定本地字体名称,再指定嵌入字体名称:

p {
    font-family: MyFontLocalName, MyFontEmbeddedName;
}

http://jsfiddle.net/gilly3/xX6Bv/5/

如果用户的计算机上安装了MyFontLocalName,将使用该字体,否则将使用MyFontEmbeddedName

【讨论】:

  • 这是一个很好的建议,但它对我不起作用。我很抱歉最初在我的帖子中没有提到这一点:我允许用户从本地文档中导入 sn-ps,这些文档通过标准名称引用该字体,所以这对他们不起作用。 :((我之前指的是不同名称的字体,“X”和“X Embedded”。)
  • @Jeremy - 棘手。我之前确实想过这个问题。我想出的最好的方法是一个丑陋的 hack 并涉及 JavaScript:将一段文本放入一个具有所需字体和一个非常大尺寸的后备字体的 span 中,例如 font-size: 200px; font-family: MyEmbeddableFont, Arial。根据测试字体的预期宽度检查跨度的宽度。如果宽度关闭,则动态加载字体。
猜你喜欢
  • 2014-09-04
  • 1970-01-01
  • 2011-09-11
  • 2011-08-01
  • 1970-01-01
  • 2019-05-15
  • 2015-06-12
  • 1970-01-01
  • 2014-01-22
相关资源
最近更新 更多