web安全字体

webfont解剖

  • Unicode字体可以包含数以千计字形
  • 有四个字体格式: WOFF2, WOFF, EOT, TTF
  • 一些字体格式需要使用GZIP压缩

一个web字体是字形的集合,且每个字形是一个描述了一个字母亦或符号的矢量图。

所以,一个字体文件的大小由两个因素决定:每个字形矢量路径的复杂程度和每个字体所包含的字形数量。

例如,Open Sans, 最流行的web字体之一, 包含了897个字形,包含了拉丁,希腊和古代斯拉夫语字母。

当选择一个字体的时候,重要的是考虑哪些字符集被支持。

例如, Google’s Noto font family 目标是支持世界上所有的语言. 但是,注意Noto的大小,因为包括了所有的语言,所以压缩后大小是130MB+。

Web字体格式

网上如今四个web字体格式: EOTTTFWOFF, 和 WOFF2.

不幸的是,虽然有很多的选择,但是没有一个字体是可以在旧的浏览器和新的浏览器上通用的:EOT只适用于IE,TTP部分被IE支持。WOFF享有最广泛的支持但是在老的浏览器中不必支持,并且对于很多新的浏览器真在添加对于WOFF 2.0的支持。

所以,这意味着我们需要使用多个字体格式来保持良好的用户体验:

  • 在支持WOFF 2.0的浏览器中使用WOFF 2.0 变体
  • 在大多数浏览器中使用WOFF字体
  • 在老的安卓(低于4.4)浏览器中使用TTF变体
  • 在老的IE(低于IE9)中使用EOT变体

使用压缩来减少字体大小

A font is a collection of glyphs, each of which is a set of paths describing the letter form. The individual glyphs are, of course, different, but they nonetheless contain a lot of similar information that can be compressed with GZIP, or a compatible compressor:

  • EOT, 和 TTF 格式默认没有压缩:确保你的服务器使用了GZIP压缩
  • WOFF 有内置的压缩 - 确保你的WOFF压缩器使用了最优化的设置。
  • WOFF2 使用了用户预定义和压缩算法来减少相对于其他字体格式约30%的文件大小

值得注意的是一些字体格式包括了额外的信息——比如font hitting和kerning信息,这些可能是不必要的,所以可以进行深入优化。

查看你的字体编译器可操作的选项,如果你可以优化上面的内容,进行优化,并在不同的浏览器中查看效果。

Note

  • 可以使用 Zopfli compression 来压缩EOT, TTF,和 WOFF 字体格式. Zopfli 是一个 zlib兼容的压缩器,压缩的内容比gzip压缩后还要小约5%。

使用 @font-face定义字体

  • 使用format()定义不同的字体格式
  • 使用大量的子集提高性能: 提供大量可选的子集可以让旧的浏览器兼容
  • 减少样式化的字体变体来提高页面和文字渲染效果

css语句@font-face定义特殊的字体资源的位置,字体样式等。

字体样式选择

每个 @font-face 声明提供了font family的名字,字体属性的什么和特殊字体来源地址的声明。

@font-face {
  font-family: ‘Awesome Font‘;
  font-style: normal;
  font-weight: 400;
  src: local(‘Awesome Font‘),
       url(‘/fonts/awesome.woff2‘) format(‘woff2‘),
       url(‘/fonts/awesome.woff‘) format(‘woff‘),
       url(‘/fonts/awesome.ttf‘) format(‘ttf‘),
       url(‘/fonts/awesome.eot‘) format(‘eot‘);
}

@font-face {
  font-family: ‘Awesome Font‘;
  font-style: italic;
  font-weight: 400;
  src: local(‘Awesome Font Italic‘),
       url(‘/fonts/awesome-i.woff2‘) format(‘woff2‘),
       url(‘/fonts/awesome-i.woff‘) format(‘woff‘),
       url(‘/fonts/awesome-i.ttf‘) format(‘ttf‘),
       url(‘/fonts/awesome-i.eot‘) format(‘eot‘);
}

上面一个 Awesome Font 字体的两个表现形式类型:正常和斜体,每个都提供了一系列的不同字体资源设置。

每个src描述符包括了一个按照优先顺序排序的,用逗号进行分隔的资源列表:

  • local() 表明我们可以使用哪些本地的字体
  • url() 指定我们加载哪些外部字体,允许我们使用format()来指代字体的格式

Note

  • 除非你指向系统的默认资源,除非很少有本地的字体资源,特别是对手机设备而言,不可能在内部安装了额外的字体。所以,你总是需要提供一个额外的字体位置清单。

浏览器按照顺序执行,上例浏览器执行如下:

  1. 浏览器显示页面布局并决定哪个字体变形被需要来渲染指定的字体;
  2. 依次检查local()中的字体是否存在并可使用;
  3. 如果本地不存在,依次检查外部字体定义:

    • 如果字体格式存在,在初始化和下载字体之间检查浏览器是否支持,如果不支持,进入下一个外部字体选项检查
    • 如果字体格式不存在,浏览器下载资源

Note

  • 外部字体加载的顺序十分重要,因为浏览器是按照这个顺序依次执行的。

Unicode-range 子集

我们可以将一个大的字体设置成小的子集(例如拉丁,希腊和斯拉夫字母等),并且只是加载这个子集来渲染页面上的字体

这个 unicode-range descriptor 允许我们指定一个逗号隔开的数据集合, 数据可以是下面三种形式中的任何一种:

  • Single codepoint (e.g. U+416)
  • Interval range (e.g. U+400-4ff): indicates the start and end codepoints of a range
  • Wildcard range (e.g. U+4??): ‘?’ characters indicate any hexadecimal digit

例如我们可以将Awesome Font设置成拉丁和日本语的子集格式,它们只有在浏览器需要的时候才会加载

@font-face {
  font-family: ‘Awesome Font‘;
  font-style: normal;
  font-weight: 400;
  src: local(‘Awesome Font‘),
       url(‘/fonts/awesome-l.woff2‘) format(‘woff2‘),
       url(‘/fonts/awesome-l.woff‘) format(‘woff‘),
       url(‘/fonts/awesome-l.ttf‘) format(‘ttf‘),
       url(‘/fonts/awesome-l.eot‘) format(‘eot‘);
  unicode-range: U+000-5FF; /* Latin glyphs */
}

@font-face {
  font-family: ‘Awesome Font‘;
  font-style: normal;
  font-weight: 400;
  src: local(‘Awesome Font‘),
       url(‘/fonts/awesome-jp.woff2‘) format(‘woff2‘),
       url(‘/fonts/awesome-jp.woff‘) format(‘woff‘),
       url(‘/fonts/awesome-jp.ttf‘) format(‘ttf‘),
       url(‘/fonts/awesome-jp.eot‘) format(‘eot‘);
  unicode-range: U+3000-9FFF, U+ff??; /* Japanese glyphs */
}

Note

  • Unicode-range subsetting is particularly important for Asian languages, where the number of glyphs is much larger than in western languages and a typical ‘full‘ font is often measured in megabytes, instead of tens of kilobytes!

The use of unicode range subsets, and separate files for each stylistic variant of the font allows us to define a composite font family that is both faster and more efficient to download - the visitor will only download the variants and subsets it needs, and they are not forced to download subsets that they may never see or use on the page.

That said, there is one small gotcha with unicode-range: not all browser support it, yet. Some browsers simply ignore the unicode-range hint and will download all variants, while others may not process the @font-face declaration at all. To address this, we need to fallback to “manual subsetting” for older browsers.

Because old browsers are not smart enough to select just the necessary subsets and cannot construct a composite font, we have to fallback to providing a single font resource that contains all necessary subsets, and hide the rest from the browser. For example, if the page is only using Latin characters, then we can strip other glyphs and serve that particular subset as a standalone resource.

  1. How do we determine which subsets are needed?

    • If unicode-range subsetting is supported by the browser, then it will automatically select the right subset. The page just needs to provide the subset files and specify appropriate unicode-ranges in the @font-face rules.
    • If unicode-range is not supported then the page needs to hide all unnecessary subsets - i.e. the developer must specify required subsets.
  2. How do we generate font subsets?
    • Use the open-source pyftsubset tool to subset and optimize your fonts.
    • Some font services allow manual subsetting via custom query parameters, which you can use to manually specify the required subset for your page - consult the documentation of your font provider.

Font selection and synthesis

Each font family is composed of multiple stylistic variants (regular, bold, italic) and multiple weights for each style, each of which, in turn, may contain very different glyph shapes - e.g. different spacing, sizing, or a different shape altogether.

For example, the above diagram illustrates a font family that offers three different bold weights: 400 (regular), 700 (bold), and 900 (extra bold). All other in-between variants (indicated in gray) are automatically mapped to the closest variant by the browser.

When a weight is specified for which no face exists, a face with a nearby weight is used. In general, bold weights map to faces with heavier weights and light weights map to faces with lighter weights.

CSS3 font matching algorithm

Similar logic applies to italic variants. The font designer controls which variants they will produce, and we control which variants we will use on the page - since each variant is a separate download, it’s a good idea to keep the number of variants small! For example, we can define two bold variants for our Awesome Fontfamily:

@font-face {
  font-family: ‘Awesome Font‘;
  font-style: normal;
  font-weight: 400;
  src: local(‘Awesome Font‘),
       url(‘/fonts/awesome-l.woff2‘) format(‘woff2‘),
       url(‘/fonts/awesome-l.woff‘) format(‘woff‘),
       url(‘/fonts/awesome-l.ttf‘) format(‘ttf‘),
       url(‘/fonts/awesome-l.eot‘) format(‘eot‘);
  unicode-range: U+000-5FF; /* Latin glyphs */
}

@font-face {
  font-family: ‘Awesome Font‘;
  font-style: normal;
  font-weight: 700;
  src: local(‘Awesome Font‘),
       url(‘/fonts/awesome-l-700.woff2‘) format(‘woff2‘),
       url(‘/fonts/awesome-l-700.woff‘) format(‘woff‘),
       url(‘/fonts/awesome-l-700.ttf‘) format(‘ttf‘),
       url(‘/fonts/awesome-l-700.eot‘) format(‘eot‘);
  unicode-range: U+000-5FF; /* Latin glyphs */
}

The above example declares the Awesome Font family that is composed of two resources that cover the same set of Latin glyphs (U+000-5FF) but offer two different “weights”: normal (400), and bold (700). However, what happens if one of our CSS rules specifies a different font weight, or sets the font-style property to italic?

  • If an exact font match is not available the browser will substitute the closest match.
  • If no stylistic match is found (e.g. we did not declare any italic variants in example above), then the browser will synthesize its own font variant.

Authors should also be aware that synthesized approaches may not be suitable for scripts like Cyrillic, where italic forms are very different in shape. It is always better to use an actual italic font rather than rely on a synthetic version.

CSS3 font-style

The example above illustrates the difference between the actual vs. synthesized font results for Open-Sans - all synthesized variants are generated from a single 400-weight font. As you can tell, there is a noticeable difference in the results. The details of how to generate the bold and oblique variants are not specified. Hence, the results will vary from browser to browser, and will also be highly dependent on the font.

Note

  • For best consistency and visual results you should not rely on font synthesis. Instead, minimize the number of used font variants and specify their locations, such that the browser can download them when they are used on the page. That said, in some cases a synthesized variant may be a viable option - use with caution.

Optimizing loading and rendering

TL;DR

  • Font requests are delayed until the render tree is constructed, which can result in delayed text rendering
  • Font Loading API allows us to implement custom font loading and rendering strategies that override default lazyload font loading
  • Font inlining allows us to override default lazyload font loading in older browsers

A “full” webfont that includes all stylistic variants, which we may not need, plus all the glyphs, which may go unused, can easily result in a multi-megabyte download. To address this, the @font-face CSS rule is specifically designed to allow us to split the font family into a collection of resources: unicode subsets, distinct style variants, and so on.

Given these declarations the browser figures out the required subsets and variants and downloads the minimal set required to render the text. This behavior is very convenient, but if we’re not careful, it can also create a performance bottleneck in the critical rendering path and delay text rendering - something that we would certainly like to avoid!

Webfonts and the Critical Rendering Path

Lazy loading of fonts carries an important hidden implication that may delay text rendering: the browser must construct the render tree, which is dependent on the DOM and CSSOM trees, before it will know which font resources it will need to render the text. As a result, font requests are delayed well after other critical resources, and the browser may be blocked from rendering text until the resource is fetched.

  1. Browser requests HTML document
  2. Browser begins parsing HTML response and constructing the DOM
  3. Browser discovers CSS, JS and other resources and dispatches requests
  4. Browser constructs the CSSOM once all CSS content is received and combines it with the DOM tree to construct the render tree
    • Font requests are dispatched once render tree indicates which font variants are needed to render the specified text on the page
  5. Browser performs layout and paints content to the screen
    • If the font is not yet available the browser may not render any text pixels
    • Once the font is available the browser paints text pixels

The “race” between the first paint of page content, which can be done shortly after the render tree is built, and the request for the font resource is what creates the “blank text problem” where the browser may render page layout but omits any text. The actual behavior differs between various browsers:

  • Safari hold text rendering until the font download is complete.
  • Chrome and Firefox hold font rendering for up to 3 seconds, after which they use a fallback font, and once the font download has finished they re-render the text once more with the downloaded font.
  • IE immediately renders with the fallback font if the request font is not yet available, and re-renders it once the font download is complete.

There are good arguments for and against the different rendering strategies: some people find re-rendering jarring while others prefer to see immediate results and don’t mind the page reflow once the font download has finished - we won’t get into this argument here. The important point is that lazyloading reduces the number of bytes, but also has the potential to delay text rendering. Next, let’s take a look at how we can optimize this behavior.

Optimizing font rendering with the Font Loading API

Font Loading API provides a scripting interface to define and manipulate CSS font faces, track their download progress, and override their default lazyload behavior. For example, if we’re certain that a particular font variant will be required, we can define it and tell the browser to initiate an immediate fetch of the font resource:

var font = new FontFace("Awesome Font", "url(/fonts/awesome.woff2)", {
  style: ‘normal‘, unicodeRange: ‘U+000-5FF‘, weight: ‘400‘
});

font.load(); // don‘t wait for render tree, initiate immediate fetch!

font.ready().then(function() {
  // apply the font (which may rerender text and cause a page reflow)
  // once the font has finished downloading
  document.fonts.add(font);
  document.body.style.fontFamily = "Awesome Font, serif";

  // OR... by default content is hidden, and rendered once font is available
  var content = document.getElementById("content");
  content.style.visibility = "visible";

  // OR... apply own render strategy here...
});

Further, because we can check font status (via check()) method and track its download progress, we can also define a custom strategy for rendering text on our pages:

  • We can hold all text rendering until the font is available.
  • We can implement a custom timeout for each font.
  • We can use the fallback font to unblock rendering and inject a new style that uses desired font once the font is available.

Best of all, we can also mix and match above strategies for different content on the page - e.g. hold text rendering on some sections until font is available, use a fallback and then rerender once the font download has finished, specify different timeouts, and so on.

Note

Optimizing font rendering with inlining

A simple alternative strategy to using the Font Loading API to eliminate the “blank text problem” is to inline the font contents into a CSS stylesheet:

  • CSS stylesheets with matching media queries are automatically downloaded by the browser with high priority as they are required to construct the CSSOM.
  • Inlining the font data into CSS stylesheet forces the browser to download the font with high priority and without waiting for the render tree - i.e. this acts as a manual override to the default lazyload behavior.

The inlining strategy is not as flexible and does not allow us to define custom timeouts or rendering strategies for different content, but it is a simple and robust solution that works across all browsers. For best results, separate inlined fonts into standalone stylesheet and serve them with a long max-age - this way, when you update your CSS you are not forcing your visitors to redownload the fonts.

Note

  • Use inlining selectively! Recall that the reason @font-face uses lazyload behavior is to avoid downloading unnecessary font variants and subsets. Also, increasing the size of your CSS via aggressive inlining will negatively impact your critical rendering path - the browser must download all CSS before it can construct the CSSOM, build the render tree, and render page contents to the screen.

Optimizing font reuse with HTTP Caching

Font resources are, typically, static resources that don’t see frequent updates. As a result, they are ideally suited for a long max-age expiry - ensure that you specify both a conditional ETag header, and an optimal Cache-Control policy for all font resources.

There is no need to store fonts in localStorage or via other mechanisms - each of those has their set of performance gotchas. The browser’s HTTP cache, in combination with Font Loading API or the webfontloader library, provides the best and most robust mechanism to deliver font resources to the browser.

Optimization checklist

Contrary to popular belief, use of webfonts does not need to delay page rendering or have negative impact on other performance metrics. Well optimized use of fonts can deliver a much better overall user experience: great branding, improved readability, usability, and searchability, all the while delivering a scalable multi-resolution solution that adapts well to all screen formats and resolutions. Don’t be afraid to use webfonts!

That said, a naive implementation may incur large downloads and unnecessary delays. This is where we need to dust off our optimization toolkit and assist the browser by optimizing the font assets themselves and how they are fetched and used on our pages.

  1. Audit and monitor your font use: do not use too many fonts on your pages, and for each font, minimize the number of used variants. This will assist in delivering a more consistent and a faster experience for your users.
  2. Subset your font resources: many fonts can be subset, or split into multiple unicode-ranges to deliver just the glyphs required by a particular page - this reduces the filesize and improves download speed of the resource. However, when defining the subsets be careful to optimize for font re-use - e.g. you don’t want to download a different but overlapping set of characters on each page. A good practice is to subset based on script - e.g. Latin, Cyrillic, and so on.
  3. Deliver optimized font formats to each browser: each font should be provided in WOFF2, WOFF, EOT, and TTF formats. Make sure to apply GZIP compression to EOT and TTF formats, as they are not compressed by default.
  4. Specify revalidation and optimal caching policies: fonts are static resources that are infrequently updated. Make sure that your servers provide a long-lived max-age timestamp, and a revalidation token, to allow for efficient font re-use between different pages.
  5. Use Font Loading API to optimize the Critical Rendering Path: default lazyloading behavior may result in delayed text rendering. Font Loading API allows us to override this behavior for particular fonts, and to specify custom rendering and timeout strategies for different content on the page. For older browsers that do not support the API, you can use the webfontloader JavaScript library or use the CSS inlining strategy.
Authorsweb web
时间: 2024-08-05 19:47:13

web安全字体的相关文章

css3之@font-face---再也不用被迫使用web安全字体了

1,@font-face 的出现在没有css3之前,我们给网页设计字体只能设置web安全字体,使得我们的网页表现看上去好像都是那个样子,那么如果我们想给字体设置web设计者提供的字体呢?没有问题,css中的@font-face 就可以帮助你解决这个问题.原理是通过将字体文件存储到服务器,再需要时被自动下载到用户的计算机中,缺点:这种字体好像是收费的,可能会影响加载速度,不过在当今的网速下,为了美加载速度可以忽略不计 2,@font-face 的使用@font-face 这个属性怎么使用呢?也就是

网页设计中常用的Web安全字体

但多数情况下,考虑各个因素的影响我们还是在尽量充分利用这些默认调用的字体实现CSS的编写,这里整理了19个Web安全字体,让你无需任何顾虑的情况下畅快使用. 1,  Arial 微软公司的网页核心字体之一,最常用的sans-serif字体,当字号很小时不容易阅读.但是,大写的“I”和小写的“l”是无法区别的,你可以考虑用Tahoma字体来替代.(苹果系统没有这种字体,但有一种对应于Arial的字体叫Helvetica,它是MAC机上与Arial 字体最相似的WEB字体,是别一种非衬线字体.它是一

中文字体名称对照表(unicode码)及20个web安全字体

在Web编码中,CSS默认应用的Web字体是有限的,虽然在新版本的CSS3,我们可以通过新增的@font-face属性来引入特殊的浏览器加载字体.但多数情况下,考虑各个因素的影响我们还是在尽量充分利用 中文名 英文名 Unicode Unicode 2 Mac OS 华文细黑 STHeiti Light [STXihei] \534E\6587\7EC6\9ED1 华文细黑 华文黑体 STHeiti \534E\6587\9ED1\4F53 华文黑体 华文楷体 STKaiti \534E\658

网页设计中常用的19个Web安全字体

在Web编码中,CSS默认应用的Web字体是有限的,虽然在新版本的CSS3,我们可以通过新增的@font-face属性来引入特殊的浏览器加载字体.但多数情况下,考虑各个因素的影响我们还是在尽量充分利用这些默认调用的字体实现CSS的编写,这里整理了19个Web安全字体,让你无需任何顾虑的情况下畅快使用. 1,  Arial 微软公司的网页核心字体之一,最常用的sans serif字体,当字号很小时不容易阅读.但是,大写的“I”和小写的“l”是无法区别的,你可以考虑用Tahoma字体来替代.(苹果系

在前端页面中使用@font-face来显示web自定义字体【转】

本文转自W3CPLUS 的<CSS @font-face> @font-face是CSS3中的一个模块,他主要是把自己定义的Web字体嵌入到你的网页中,随着@font-face模块的出现,我们在Web的开发中使用字体不怕只能使用Web安全字体,你们当中或许有许多人会不自然的问,这样的东西IE能支持吗?当我告诉大家@font-face这个功能早在IE4就支持了你肯定会感到惊讶.我的Blog就使用了许多这样的自定义Web字体,比如说首页的Logo,Tags以及页面中的手写英文体,很多朋友问我如何使

CSS3 Web嵌入字体

CSS3嵌入Web字体一直以来Web设计师在设计网页时都想为Web页面添加一些优雅的字体,但浏览器仅限于使用用户在其系统上安装的字体呈现文本,这样一来让大部分网站受限于字体数量的不足.多年来一直都是使用图片替换文本的方式来解决页面上使用优雅字体,但这种对于频繁更换文本的网站来说是一件不切实际的事,以致于我们坚持使用这些少量的Web字体.随着技术的不断发展,出现在Web页面中 使用Flash和JavaScript技术来弥补这一不足.虽然这些方法已经是不错的应急措施, 允许包含自己的字体,但是它们拥

WEB安全字体(Web Safe Fonts)-网页设计用什么字体兼容性好?

效果:http://sandbox.runjs.cn/show/qgdljvh4 1 Arial微软公司的网页核心字体之一,最常用的sans serif字体,当字号很小时不容易阅读.但是,大写的“I”和小写的“l”是无法区别的,你可以考虑用Tahoma字体来替代.(苹果系统没有这种字体,但有一种对应于Arial的字体叫Helvetica,它是MAC机上与Arial 字体最相似的WEB字体,是别一种非衬线字体.它是一种性能优良的打印字体,但在屏幕上表现不是很好,说道Helvetica字体,昨天发现

移动Web开发字体格式选择

在做移动开发的时候,UI设计师会提供一些定制字体,来提高产品的视觉效果.对于前端开发来说,就需要考虑字体文件的兼容性和文件的大小,在尽量保证UI效果的情况下,兼容更多的浏览器,减少资源体积,使UI效果.兼容性.性能三者达到平衡.由于中文字体字符集的限制,最终字体包文件都会很大,这里不做讨论.下面主要介绍英文.数字符号场景下几种常见的字体格式. .ttfTrueType,是Type 1(Adobe公司开发)的竞品,由苹果公司和微软一起开发,是mac系统和window系统用的最广泛的字体,一般从网上

移动web页面字体大小三

<script type="text/javascript"> (function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', recalc = function () { var clientWidth = docEl.clientWidth; if (!clientWidt