如何使用 header 标签内的 <link href=... 格式从我的服务器加载自定义 Web 字体

How to load a custom web font face from my server using <link href=... format inside the header tags

我不希望使用@font-face 声明自定义字体时出现渲染阻塞,所以我尝试复制我的 google 字体 CDN 字体是如何为我的自定义服务器字体加载的,到达这里:

    <noscript id="deferred-styles">
  <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet" type="text/css">
  <link href="../BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext" rel="stylesheet" type="text/css">
</noscript>

但是不行。

我试过为 src="../Bluu... 更改 href 但这没有用。

我试过省略类型,因为 woff2 不是 text/css。

这很重要,我不愿意为 35kb 的字体文件阻止我的页面加载,而且 BluuNext 没有 CDN,所以我需要找到一种高效的方法来完成这项工作,否则我会辞职的到一个米色网站。

正确!

我试过下面的答案,可能它们适用于其他字体但不适用于 BluuNext。与 BluuNext 不同,也许其他字体的配置可能超出粗体,所以这可能会导致问题。

可以加载 BluuNext 字体,但目前只能使用渲染阻塞@font-face 方法,在标签之间加载。

这是一个最小的例子,其中包括一些建议的解决方案不起作用...

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:fb="http://ogp.me/ns/fb#">
  <head>
    <title>Bluu Next test</title>

<link rel="preload" as="style" href="../BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext:bold"  />
<link rel="stylesheet" href="../BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext" media="print" onload="this.media='all'">
<link rel="stylesheet" media="print" onload="this.media='all'" href="../BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext:bold"  type="text/css" />
    
<noscript id="deferred-styles">
  <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet" type="text/css">
  <link rel="stylesheet" href="../BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext:bold" type="text/css"/>
</noscript>

<script type="text/javascript">
    // Load CSS
    var loadDeferredStyles = function() {
        var addStylesNode = document.getElementById("deferred-styles");
        var replacement = document.createElement("div");
        replacement.innerHTML = addStylesNode.textContent;
        document.body.appendChild(replacement)
        addStylesNode.parentElement.removeChild(addStylesNode);
    };
    var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
        window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
    if (raf) raf(function() { window.setTimeout(loadDeferredStyles, 0); });
    else window.addEventListener('load', loadDeferredStyles);
</script>

<style>
    h2{font-family: bluuNext; font-size: 3em;}
</style>
</head><body>
<h2>Is this Bluu Next?</h2> 
  </body>
</html>

你可以看到一些奇特的 javascript 管理 id="deferred-styles" 的加载,这是在 Google lighthouse 的建议下出现的,并且适用于 Google 的 CDN 字体, 到目前为止还没有为 BluuNext 工作。

这是 link to download BluuNext,一种可爱的哥特式衬线字体。单击右上角的下载箭头。

我喜欢一些想法。我喜欢使用这种特殊的字体,由于某种原因,它似乎对现有解决方案有抵抗力。

  • async 风格 <link rel="stylesheet" /> 元素的现代方法是使用 media="print"onload="this.media='all'"

    • media="print" 属性意味着浏览器应该 仍然下载样式表,但不会阻止页面加载。

    • onload="this.media='all'" event-handler 会导致样式表在 加载时启用

    • 因为浏览器 可能 仍然根本不下载 print 样式表,您还应该添加一个明确的 <link rel="preload" /> 版本(对于相同的样式表)作为一个强烈的提示浏览器应该下载它。

    • 然而,仍然 取决于浏览器是否启用了 JavaScript 以便 onload="" 处理程序工作。

    • ...因此需要在 <noscript> 包装器元素中复制代码。

  • 此外,您确实应该在 <link href="" 属性中使用 root-relative(即“/foo”样式)URI,否则它们将无法工作用户没有访问您站点根目录中的页面。

    • 我假设您的 BluuNext-master 目录位于您站点的根目录中。

所以把你的HTML改成这样:

<head>

    <!-- onload+media trick to defer loading these stylesheets: -->
    <link rel="preload" as="style" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"  />
    <link rel="preload" as="style" href="/BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext"  />

    <link rel="stylesheet" media="print" onload="this.media='all'" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"  type="text/css" />
    <link rel="stylesheet" media="print" onload="this.media='all'" href="/BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext"  type="text/css" />

    <!-- But if Javascript is used the <noscript> will ensure the browser will load it: -->
    <noscript>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"  type="text/css" />
        <link rel="stylesheet" href="/BluuNext-master/Fonts/webfonts/bluunext-bold-webfont.woff2?family=bluuNext"  type="text/css" />
    </noscript>

</head>

我确实认为我们需要基本上重复自己三遍来解决本应属于 HTML 的问题,这很愚蠢。

您不能直接在 HTML 中加载字体,为此您需要 CSS 的帮助。如果您打开 google 字体 link,您将能够看到它是如何完成的。

https://fonts.googleapis.com/css?family=Roboto:300,400,500

这个 url 是一个 css 文件而不是字体文件。 打开你就会明白google是如何使用@font-face加载字体的。

这是来自 mdn 的文档: https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face