CSS 在渲染网页之前等待字体加载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4712242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 23:29:37  来源:igfitidea点击:

Wait for fonts to load before rendering web page

cssfontsfont-face

提问by wheresrhys

I'm using @font-face to embed fonts in my website. First the text renders as the system default, and then (once the font file has loaded presumably) the correct font renders a fraction of a second later. Is there a way to minimise/get rid of this delay, by delaying the page rendering until after fonts have loaded or similar.

我正在使用 @font-face 在我的网站中嵌入字体。首先文本呈现为系统默认值,然后(一旦字体文件可能已加载)正确的字体在几分之一秒后呈现。有没有办法通过将页面渲染延迟到字体加载或类似之后来最小化/摆脱这种延迟。

采纳答案by Tom Gullen

This is down to how the browser behaves.

这取决于浏览器的行为方式。

First off where is your @font declared? Is it inline to your HTML, declared in a CSS sheet on the page, or (hopefully) declared in an external CSS sheet?

首先你的@font 在哪里声明?它是嵌入到您的 HTML 中,在页面上的 CSS 表中声明,还是(希望)在外部 CSS 表中声明?

If it is not in an external sheet, try moving it to one (this is better practice anyway usually).

如果它不在外部工作表中,请尝试将其移动到一个(通常这是更好的做法)。

If this doesn't help, you need to ask yourself is the fraction of a second difference really significantly detrimental to the user experience? If it is, then consider JavaScript, there are a few things you might be able to do, redirects, pauses etc, but these might actually be worsethan the original problem. Worse for users, and worse to maintain.

如果这没有帮助,您需要问自己一秒钟的差异是否真的对用户体验有显着的不利影响?如果是,那么请考虑 JavaScript,您可能可以执行一些操作,重定向、暂停等,但这些实际上可能比原始问题更糟。对用户来说更糟糕,更糟糕的是维护。

This link might help:

此链接可能有帮助:

http://paulirish.com/2009/fighting-the-font-face-fout/

http://paulirish.com/2009/fighting-the-font-face-fout/

回答by Ryan Taylor

Edit:The best approach is probably to base64 encode your fonts. This means your font will have to be loaded fully by the time your HTML is parsed and displayed. You can do this with font squirrel's webfont generator https://www.fontsquirrel.com/tools/webfont-generatorby clicking "Expert" and then "base64 encode". This is how services like TypeKit work.

编辑:最好的方法可能是base64 编码您的字体。这意味着您的字体必须在您的 HTML 被解析和显示时完全加载。您可以使用 font squirrel 的 webfont 生成器https://www.fontsquirrel.com/tools/webfont-generator通过单击“专家”然后单击“base64 编码”来执行此操作。这就是 TypeKit 之类的服务的工作方式。



Original answer:Another way to detect if fonts are loaded would be using FontLoader https://github.com/smnh/FontLoaderor by copying their strategy.

原始答案:另一种检测字体是否已加载的方法是使用 FontLoader https://github.com/smnh/FontLoader或通过复制其策略。

They bind to the scroll event in the browser, because when the font loads it will resize the text. It uses two containing divs (that will scroll when the height changes) and a separate fallback for IE.

它们绑定到浏览器中的滚动事件,因为当字体加载时,它会调整文本大小。它使用两个包含的 div(当高度改变时会滚动)和一个单独的 IE 回退。

An alternative is to check the DOM periodically with setInterval, but using javascript events is far faster and superior.

另一种方法是setInterval使用定期检查 DOM ,但使用 javascript 事件要快得多,而且效果更好。

Obviously, you might do something like set the opacity of body to 0 and then display it in once the font loads.

显然,您可能会执行一些操作,例如将 body 的不透明度设置为 0,然后在字体加载后将其显示。

回答by davecave

Joni Korpi has a nice article on loading fonts before the rest of the page.

Joni Korpi 有一篇关于在页面其余部分之前加载字体的好文章。

http://jonikorpi.com/a-smoother-page-load/

http://jonikorpi.com/a-smoother-page-load/

He also uses a loading.gif to alleviate the delay so users won't get frustrated.

他还使用 loading.gif 来缓解延迟,这样用户就不会感到沮丧。

回答by Thiago C. S Ventura

Since nobody mentioned that, I believe this question needs an update. The way I managed to solve the problem was using the "preload" option supported by modern browsers.

由于没有人提到这一点,我相信这个问题需要更新。我设法解决问题的方法是使用现代浏览器支持的“预加载”选项。

In case someone does not need to support old browsers.

如果有人不需要支持旧浏览器。

<link rel="preload" href="assets/fonts/xxx.woff" as="font" type="font/woff" crossorigin>

some useful links with more details:

一些包含更多详细信息的有用链接:

https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_contenthttp://www.bramstein.com/writing/preload-hints-for-web-fonts.html

https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content http://www.bramstein.com/writing/preload-hints-for-web-fonts.html

回答by klodoma

Use https://github.com/typekit/webfontloader

使用https://github.com/typekit/webfontloader

and check the events in the configuration https://github.com/typekit/webfontloader#configuration

并检查配置https://github.com/typekit/webfontloader#configuration 中的事件

<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
<script>
    WebFont.load({
        custom: {
            families: [ "CustomFont1", "CustomFont2" ]
        },
        active: function() {
            //Render your page
        }
    });
</script>

回答by nunopolonia

Only IE loads first the font and then the rest of the page. The other browsers load things concurrently for a reason. Imagine that there's a problem with the server hosting the font or with the font downloading. You will hang your entire site until the font is loaded. On my opinion a flash of unstyled text is better than not seeing the site at all

只有 IE 首先加载字体,然后加载页面的其余部分。其他浏览器出于某种原因同时加载内容。想象一下,托管字体的服务器或字体下载存在问题。您将挂起整个网站,直到字体加载完毕。在我看来,一闪而过的无样式文字总比根本看不到网站要好

回答by Lirianna

You can use CSS font-display inside your @font-face. The keywords for all the available values are:

您可以在 @font-face 中使用 CSS font-display。所有可用值的关键字是:

  • auto
  • block
  • swap
  • fallback
  • optional
  • 汽车
  • 堵塞
  • 交换
  • 倒退
  • 可选的

Giulio Mainardi has written a nice article about all of them, and which you should use where on sitepoint.

Giulio Mainardi 写了一篇关于所有这些的很好的文章,你应该在站点的 where 上使用它。

You can read it here: https://www.sitepoint.com/css-font-display-future-font-rendering-web/?utm_source=frontendfocus&utm_medium=email

你可以在这里阅读:https: //www.sitepoint.com/css-font-display-future-font-rendering-web/?utm_source=frontendfocus&utm_medium=email

回答by Holtwick

This code works very well for me. It uses the Font Loading APIwhich has good support among modern browsers.

这段代码对我来说效果很好。它使用在现代浏览器中具有良好支持的字体加载 API

<style>
  @font-face {
    font-family: 'DemoFont';
    font-style: normal;
    font-weight: 400;
    src: url("./fonts/DemoFont.eot");
    src: url("./fonts/DemoFont.woff2") format("woff2"),
    url("./fonts/DemoFont.woff") format("woff"),
    url("./fonts/DemoFont.ttf") format("truetype");
  }

  .font {
    font-family: 'DemoFont';
    color: transparent;
  }

  html.font-loaded .font {
    color: inherit; // Override `transparent` from .font
  }

</style>
<script>
  // Check if API exists
  if (document && document.fonts) {    
    // Do not block page loading
    setTimeout(function () {           
      document.fonts.load('16px "DemoFont"').then(() => {
        // Make font using elements visible
        document.documentElement.classList.add('font-loaded') 
      })
    }, 0)
  } else {
    // Fallback if API does not exist 
    document.documentElement.classList.add('font-loaded') 
  }
</script>

The trick is to set the CSS color to transparent for elements using the font. Once loaded this is reset by adding font-loadedclass to <html>element.

诀窍是将使用字体的元素的 CSS 颜色设置为透明。加载后,通过向元素添加font-loaded类来重置它<html>

Please replace DemoFontwith something meaningful for your project to get it work.

请替换DemoFont为对您的项目有意义的东西以使其正常工作。

回答by Nadilka Perera

(function() {
        document.getElementsByTagName("html")[0].setAttribute("class","wf-loading")
        document.getElementsByTagName("html")[0].setAttribute("className","wf-loading")
    })();

use this method.. use with Webfont.js

使用这种方法.. 与 Webfont.js 一起使用

回答by benhowdle89

Maybe something like this:

也许是这样的:

$("body").html("<img src='ajax-loader.gif' />");

Then when the page loads, replace body's content with the actual content and hopefully, fully rendered fonts, you may have to play around with this though...

然后当页面加载时,用实际内容替换正文的内容,并希望完全呈现字体,但你可能不得不玩这个......